最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布
最新IP地址数据库 来自 qqzeng.com
利用二分逼近法(bisection method) ,每秒500多万, 比较高效!
多语言API解析Dat 导入数据库脚本
https://github.com/zengzhan/qqzeng-ip



原来的顺序查找算法 效率比较低
readonly string ipBinaryFilePath = "qqzengipdb.dat";
readonly byte[] dataBuffer, indexBuffer;
readonly uint[] index = new uint[];
readonly int dataLength;
public IpLocation()
{
try
{
FileInfo file = new FileInfo(ipBinaryFilePath);
dataBuffer = new byte[file.Length];
using (var fin = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
fin.Read(dataBuffer, , dataBuffer.Length);
}
var offset_len = BytesToLong(dataBuffer[], dataBuffer[], dataBuffer[], dataBuffer[]); //Big Endian
indexBuffer = new byte[offset_len];
Array.Copy(dataBuffer, , indexBuffer, , offset_len);
dataLength = (int)offset_len;
for (int loop = ; loop < ; loop++)
{
//索引 四字节 LITTLE_ENDIAN
index[loop] = BytesToLong(indexBuffer[loop * + ], indexBuffer[loop * + ], indexBuffer[loop * + ], indexBuffer[loop * ]);
}
}
catch { }
} public string[] Find(string ip)
{
var ips = ip.Split('.');
uint ip_prefix = uint.Parse(ips[]);
uint find_uint32 = BytesToLong(byte.Parse(ips[]), byte.Parse(ips[]), byte.Parse(ips[]), byte.Parse(ips[]));//BIG_ENDIAN // LITTLE_ENDIAN
int max_len = ;
int resultOffset =-;
int resultLegth =-; uint start = index[ip_prefix] * + ;
if (ip_prefix != )
{
max_len = (int)index[ip_prefix + ] * + ;
}
else
{
max_len = (int)index[] * + +;
} for (; start < max_len; start += )
{
// 前四位 结束ip 后三位 偏移 最后一位 内容长度
uint endipNum = BytesToLong(indexBuffer[start + ], indexBuffer[start + ], indexBuffer[start + ], indexBuffer[start + ]);//BIG_ENDIAN
if (endipNum >= find_uint32)
{
resultOffset =(int) BytesToLong((byte), indexBuffer[start + ], indexBuffer[start + ], indexBuffer[start + ]);//LITTLE_ENDIAN
resultLegth = 0xFF & indexBuffer[start + ];// 长度
break;
}
}
if (resultOffset==-||resultLegth==-)
{
return new string[] {"N/A"};
}
var areaBytes = new byte[resultLegth];
Array.Copy(dataBuffer, dataLength + resultOffset - , areaBytes, , resultLegth);
return Encoding.UTF8.GetString(areaBytes).Split(' ');
} private static uint BytesToLong(byte a, byte b, byte c, byte d)
{ return ((uint)a << ) | ((uint)b << ) | ((uint)c << ) | (uint)d;
} public static string long2IP(long longIP)
{
StringBuilder sb = new StringBuilder("");
sb.Append(longIP >> );
sb.Append(".");
//将高8位置0,然后右移16为 sb.Append((longIP & 0x00FFFFFF) >> );
sb.Append("."); sb.Append((longIP & 0x0000FFFF) >> );
sb.Append(".");
sb.Append((longIP & 0x000000FF)); return sb.ToString(); }
}
改进版 采用二分逼近 算法(类似二分查找,但又不同) 性能提升很大
public string[] Find(string ip)
{
var ips = ip.Split('.');
uint ip_prefix = uint.Parse(ips[]);
uint find_uint32 = BytesToLong(byte.Parse(ips[]), byte.Parse(ips[]), byte.Parse(ips[]), byte.Parse(ips[]));//BIG_ENDIAN
uint max_len = ;
int resultOffset = -;
int resultLegth = -;
uint start = index[ip_prefix];
if (ip_prefix != )
{
max_len = index[ip_prefix + ];
}
else
{
max_len = index[];
}
uint num = max_len - start;
uint my_index = BinarySearch(start, max_len, find_uint32);
start = my_index * + ;
resultOffset = (int)BytesToLong((byte), indexBuffer[start + ], indexBuffer[start + ], indexBuffer[start + ]);//LITTLE_ENDIAN
resultLegth = 0xFF & indexBuffer[start + ];// 长度 if (resultOffset == - || resultLegth == -)
{
return new string[] { "N/A" };
}
var areaBytes = new byte[resultLegth];
Array.Copy(dataBuffer, dataLength + resultOffset - , areaBytes, , resultLegth);
return Encoding.UTF8.GetString(areaBytes).Split(' ');
} /// <summary>
/// 二分逼近
/// </summary>
public uint BinarySearch(uint low, uint high, uint k)
{
uint M = ;
while (low <= high)
{
uint mid = (low + high) / ;
uint endipNum = GetStartIp(mid);
if (endipNum >= k)
{
M = mid; //mid有可能是解
high = mid - ;
}
else
low = mid + ;
}
return M;
}
有了上面高效算法 解析出来800多万数据 也很快 再用一个简单的ling 统计一下即可
var cn_result= from r in list
group r by r.cn into g
select new { key = g.Key, cnt = g.Count() };
800多万数据 统计组图






微信公众号:qqzeng-ip

IP地址数据库: 
最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布的更多相关文章
- 最新IP地址数据库Dat格式-高性能高并发版(2017年1月)
最新IP地址数据库->Dat格式 高性能格式->qqzeng-ip.dat 国内版-20170101-Dat 版 国外版-20170101-Dat 版 ...
- 最新IP地址数据库Dat格式-高性能高并发版(2019年3月)
最新IP地址数据库->Dat 二进制文件 高性能高并发-qqzeng-ip.dat 格式 全球IP数据库-20190301-Dat 版 国内IP数据库-20190 ...
- 最新IP地址数据库
2016年12月1日 最新发行版 265051条数据 基于:国内基于省市区以及运营商 国外基于国家 版本:全球旗舰版 国内精华版 国外拓展版 英文版 掩码版 字段:大洲 国家 省份 城市 县区 运营 ...
- IP地址数据库 | 手机号段归属地数据库 | 行政区划省市区数据库
2019年4月最新版 IP地址数据库 (全球版·国内版·国外版·掩码版·英文版) 全球旗舰版 454267行 国内精华版 244379行 演示 https://www.qqzeng.com/ip ...
- IP地址数据库-ISP运营商列表(2017年1月)
IP地址数据库 微信号:qqzeng-ip [全球旗舰版][国内精华版][国外拓展版][英文版][掩码版] http://qqzeng.com 中国大陆:三大基础运营商 中国电信中国联通中国 ...
- 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳
互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需要我来考虑,虽然我们没 ...
- 数据库已经最优,每次操作50万条数据,怎么提高API接口的速度?
第一种可以使用负载均衡,10台,就每台5W条数据第二种每台机器.可以把添加任务队列.利用多线程解决IO密集型任务的特点.第三种利用异步协程方式提高调度行为
- 手机号段、ip地址归属地大全,最新手机号段归属地,IP地址归属地数据库
百事通:http://www.114best.com/dh/114.aspx?w=17097232323,联通识别为电信的,1349错 二三四五:http://tools.2345.com/frame ...
- PHP利用纯真IP数据库在本地实现IP地址信息查询
https://blog.csdn.net/myweishanli/article/details/45098693 准备工作: 建议本地IP地址数据库,请到http://www.cz88.net/这 ...
随机推荐
- *HDU3038 并查集
How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- Unity3D设计原则
原则1:单一职责 原则2:里氏替换原则(子类扩展但不改变父类功能) 原则3:依赖倒置原则 原则4:接口隔离原则 原则5:迪米特法则(最少知道原则) 原则6:开闭原则 原则1:单一职责原则 说到单一职责 ...
- IOS 开发调用打电话,发短信
1.调用 自带mail[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@hzl ...
- 72. 求m到n之和
求m到n之和 int sum(int m, int n) { int i, result = 0; for (i=m; i<=n; i++) result = result+i; return ...
- 掌握Thinkphp3.2.0----CURD
TP-----CURD create()创建数据----整理数据 在数据库添加等操作之前,我们首先需要对数据进行创建.何为数据创建,就是接受提交过来的数据,比如表单提交的 POST(默认)数据.接受 ...
- Symmetric Multiprocessor Organization
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION
- 解决mysql数据库插入中文字段时出现??? 的问题
1.检查并修改mysql的my.ini的配置文件 default-character-set=utf8 2.建立数据库是要指定字符集 create database mydb default ...
- 关于MVC4.0中@Styles.Render用法与详解
本文分享于http://keleyi.com/a/bjac/q74dybjc.htm文章,感觉写的蛮好所以就拿过来做笔记了,希望对大家有帮助 最近公司的新项目用了MVC 4.0,接下来一步步把 工作中 ...
- Elong App 性能测试分享
个人简介: 测试老鸟,曾做过6年的测试以及2年的大数据开发:曾就职于伟景行.高德(大数据开发):钟情于钻研开源测试框架:目前挂单于艺龙. 有对本主题感兴趣的同学,可以加我Q私信(305285925): ...
- spark-submit 分发应用
Spark 提供了一个名为spark-submit 的单一工具来跨集群管理器的提交作业,命令如下: bin/spark-submit [options] <app jar | python fi ...