手机号码归属地 mysql_最新手机号段归属地数据库 (2021年1月版) 471402行

这是一个使用C#实现的高效手机号码归属地查询程序,通过内存优化的dat文件存储数据,能每秒解析300万+号段或号码。程序通过观察dat文件变动自动加载最新数据,支持二分搜索算法进行快速查询。
摘要由CSDN通过智能技术生成

//名称:手机号码归属地查询 dat高效率查询 内存优化版//压缩:原版txt为22M,生成这种dat结构为2.66M//性能:每秒解析300万+号段或者号码,简洁高效//环境:CPU i7-7700K +内存16GB//创建:qqzeng-ip

usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Text;usingSystem.Threading;namespaceqqzeng_phone_dat

{public classPhoneSearchFast

{private static readonly Lazy lazy = new Lazy(() => newPhoneSearchFast());public static PhoneSearchFast Instance { get { returnlazy.Value; } }privatePhoneSearchFast()

{

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;///

///初始化二进制dat数据///

///

///

private voidLoadDat()

{

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

{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 voidWatch()

{

FileInfo fi= newFileInfo(datPath);

FileSystemWatcher watcher= newFileSystemWatcher(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;

}///

///号段查询///

/// 7位或者11位

///

public string Query(stringphone)

{longpref;long val = PhoneToInt(phone, outpref);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 "";

}

}///

///二分算法///

private int BinarySearch(long low, long high, longkey)

{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 longprefix)

{//最高性能

charch;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;returncurrentValue;

}//prefix = Convert.ToUInt32(phone.Substring(0,3));//return Convert.ToUInt32(phone.Substring(0, 7)); ;

}///

///字节转整形 小节序///

private uint BytesToLong(byte a, byte b, byte c, byted)

{return (uint)(a | (b << 8) | (c << 16) | (d << 24));

}

}/*(调用例子):

string result = PhoneSearchFast.Instance.Query("号段|号码");

--> result="省份|城市|区号|邮编|行政区划代码|运营商"*/}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值