大家好,又见面了,我是你们的朋友全栈君。
最新 手机号段数据库 2020-08-15 458461条记录 号码归属地数据库 全面 准确 规范
字段包括 省份 城市 运营商 邮编 区号 等信息,对于数据分析、号码归属地查询等非常有帮助
名称:手机号码归属地查询 dat高效率查询 内存优化版
压缩:原版txt为22M,生成这种dat结构为2.66M
性能:每秒解析300万+号段或者号码,简洁高效
环境:CPU i7-7700K +内存16GB
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
namespace qqzeng_phone_dat
{
public class PhoneSearchFast
{
private static readonly Lazy<PhoneSearchFast> lazy = new Lazy<PhoneSearchFast>(() => new PhoneSearchFast());
public static PhoneSearchFast Instance { get { return lazy.Value; } }
private PhoneSearchFast()
{
LoadDat();
Watch();
}
private string datPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"qqzeng-phone.dat");
private DateTime lastRead = DateTime.MinValue;
private long[,] prefmap = new long[200, 2];// 000-199
private long[,] phonemap;
private byte[] data;
private long[] phoneArr;
private string[] addrArr;
private string[] ispArr;
/// <summary>
/// 初始化二进制dat数据
/// </summary>
/// <param name="dataPath"></param>
///
private void LoadDat()
{
data = File.ReadAllBytes(datPath);
long PrefSize = BytesToLong(data[0], data[1], data[2], data[3]);
long RecordSize = BytesToLong(data[4], data[5], data[6], data[7]);
long descLength = BytesToLong(data[8], data[9], data[10], data[11]);
long ispLength = BytesToLong(data[12], data[13], data[14], data[15]);
//内容数组
int descOffset = (int)(16 + PrefSize * 9 + RecordSize * 7);
string descString = Encoding.UTF8.GetString(data, descOffset, (int)descLength);
addrArr = descString.Split('&');
//运营商数组
int ispOffset = (int)(16 + PrefSize * 9 + RecordSize * 7 + descLength);
string ispString = Encoding.UTF8.GetString(data, ispOffset, (int)ispLength);
ispArr = ispString.Split('&');
//前缀区
int m = 0;
for (var k = 0; k < PrefSize; k++)
{
int i = k * 9 + 16;
int n = data[i];
prefmap[n, 0] = BytesToLong(data[i + 1], data[i + 2], data[i + 3], data[i + 4]);
prefmap[n, 1] = BytesToLong(data[i + 5], data[i + 6], data[i + 7], data[i + 8]);
if (m < n)
{
for (; m < n; m++)
{
prefmap[m, 0] = 0; prefmap[m, 1] = 0;
}
m++;
}
else
{
m++;
}
}
//索引区
phoneArr = new long[RecordSize];
phonemap = new long[RecordSize, 2];
for (int i = 0; i < RecordSize; i++)
{
long p = 16 + PrefSize * 9 + (i * 7);
phoneArr[i] = BytesToLong(data[p], data[1 + p], data[2 + p], data[3 + p]);
phonemap[i, 0] = data[4 + p] + ((data[5 + p]) << 8);
phonemap[i, 1] = data[6 + p];
}
}
private void Watch()
{
FileInfo fi = new FileInfo(datPath);
FileSystemWatcher watcher = new FileSystemWatcher(fi.DirectoryName)
{
IncludeSubdirectories = false,
NotifyFilter = NotifyFilters.LastWrite,
Filter = "qqzeng-phone.dat",
};
watcher.Changed += (s, e) =>
{
var lastWriteTime = File.GetLastWriteTime(datPath);
if (lastWriteTime > lastRead)
{
//延时 解决 正由另一进程使用,因此该进程无法访问此文件
Thread.Sleep(1000);
LoadDat();
lastRead = lastWriteTime;
}
};
watcher.EnableRaisingEvents = true;
}
/// <summary>
/// 号段查询
/// </summary>
/// <param name="phone">7位或者11位</param>
/// <returns></returns>
public string Query(string phone)
{
long pref;
long val = PhoneToInt(phone, out pref);
long low = prefmap[pref, 0], high = prefmap[pref, 1];
if (high == 0)
{
return "";
}
long cur = low == high ? low : BinarySearch(low, high, val);
if (cur != -1)
{
return addrArr[phonemap[cur, 0]] + "|" + ispArr[phonemap[cur, 1]];
}
else
{
return "";
}
}
/// <summary>
/// 二分算法
/// </summary>
private int BinarySearch(long low, long high, long key)
{
if (low > high)
return -1;
else
{
long mid = (low + high) / 2;
long phoneNum = phoneArr[mid];
if (phoneNum == key)
return (int)mid;
else if (phoneNum > key)
return BinarySearch(low, mid - 1, key);
else
return BinarySearch(mid + 1, high, key);
}
}
private long PhoneToInt(string phone, out long prefix)
{
//最高性能
char ch;
long currentValue = 0;
long prefval = 0;
unsafe
{
fixed (char* name = phone)
{
for (int current = 0; current < 7; current++)
{
ch = name[current];
int digitValue = ch - '0';
currentValue = (currentValue * 10) + digitValue;
if (current == 2)
{
prefval = currentValue;
}
}
}
prefix = prefval;
return currentValue;
}
//prefix = Convert.ToUInt32(phone.Substring(0,3));
//return Convert.ToUInt32(phone.Substring(0, 7)); ;
}
/// <summary>
/// 字节转整形 小节序
/// </summary>
private uint BytesToLong(byte a, byte b, byte c, byte d)
{
return (uint)(a | (b << 8) | (c << 16) | (d << 24));
}
}
/*
(调用例子):
string result = PhoneSearchFast.Instance.Query("号段|号码");
--> result="省份|城市|区号|邮编|行政区划代码|运营商"
*/
}
更新历史:
2020-08-15 458461条记录
2020-08-01 458084条记录
2020-07-15 458020条记录
2020-07-01 457441条记录
2020-06-01 454802条记录
2020-05-01 450433条记录
2020-04-01 450175条记录
2020-03-01 447897条记录
2020-01-01 442612条记录
2019-12-01 441831条记录
2019-11-01 439265条记录
2019-09-01 438615条记录
2019-08-01 437142条记录
2019-07-01 436804条记录
2019-06-01 430826条记录
2019-05-01 429052条记录
2019-04-01 424014条记录
2019-03-01 423850条记录
2019-02-01 423766条记录
2019-01-01 421973条记录
2018-12-01 415967条记录
2018-11-01 415806条记录
2018-10-01 415311条记录
2018-09-01 413015条记录
2018-08-01 411856条记录
2018-07-01 410765条记录
2018-06-01 405385条记录
2018-05-01 387892条记录
2018-03-01 382140条记录
2018-02-01 381409条记录
2018-01-01 381061条记录
2017-12-01 380357条记录
2017-11-01 369022条记录
2017-10-01 368360条记录
2017-08-01 366454条记录
2017-07-01 363952条记录
2017-06-01 362386条记录
2017-05-01 359938条记录
2017-04-01 359429条记录
2017-03-01 358215条记录
2017-02-01 358006条记录
2017-01-01 357213条记录
2016-12-01 354586条记录
2016-11-01 352898条记录
2016-10-15 352182条记录
2016-09-15 352176条记录
2016-08-15 352069条记录
2016-07-15 344348条记录
2016-06-15 343198条记录
2016-05-15 335588条记录
2016-04-15 335169条记录
2016-03-25 334447条记录
2016-03-01 331878条记录
2016-02-01 329833条记录
2016-01-01 327154条记录
2015-12-01 326601条记录
2015-11-01 326596条记录
2015-10-01 324557条记录
2015-09-01 321602条记录
2015-08-01 320432条记录
2015-07-01 320027条记录
2015-06-01 318201条记录
2015-05-01 318115条记录
2015-04-01 317191条记录
2015-03-01 312145条记录
2015-02-01 311924条记录
2015-01-01 310165条记录
2014-12-01 309966条记录
2014-11-01 309398条记录
2014-10-01 307924条记录
2014-09-01 306093条记录
2014-08-01 301472条记录
2014-07-01 303033条记录
2014-06-01 300635条记录
2014-05-01 299920条记录
2014-04-01 296010条记录
2014-03-01 289087条记录
2014-02-01 288831条记录
2014-01-01 288661条记录
2013-12-01 287379条记录
2013-11-01 286438条记录
2013-10-01 286418条记录
2013-09-01 284304条记录
2013-08-01 282136条记录
2013-07-01 281965条记录
2013-06-03 281413条记录
2013-05-03 281071条记录
2013-04-01 279680条记录
2013-03-01 276893条记录
2013-02-01 275967条记录
2013-01-01 274995条记录
2012-12-01 274832条记录
…………
Excel vlookup 函数 xls 使用
归属地公式:=(VLOOKUP(LEFT(B2,7),号段数据库!B:D,2,0)&VLOOKUP(LEFT(B2,7),号段数据库!B:D,3,0))
运营商公式:=(VLOOKUP(LEFT(A2,3),isp!A:B,2,0))
运营商公式:=(VLOOKUP(LEFT(B2,7),号段数据库!B:E,4,0))
两个列合并:=CONCATENATE(B1&C1)
开发参考 GitHub https://github.com/zengzhan/qqzeng-ip
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163138.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...