最新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/这 ...
随机推荐
- 【DP】HDU 1176
HDU 1176 免费馅饼 题意:中文题目不解释. 思路:因为是从中间出发所以思路卡了许久,还在之前做了道HIHO入门的题.能想到的点,从时间思考,然后初始化1s的时候,4,5,6,的数值要特别赋值. ...
- C#中的Json的序列化和反序列化
Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...
- OSG中找到特定节点的方法
OSG中找到特定节点的方法 转自:http://38288890.blog.163.com/blog/static/19612845320072721549504/ 为了在OSG中找到需要的节点并对节 ...
- 【超级干货】手机移动端WEB资源整合
meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...
- linq To DataTable
//将IEnumerable<T>类型的集合转换为DataTable类型 1111 public static DataTable LINQToDataTable<T>(IEn ...
- php调试局部错误强制输出 display_errors
error_reporting(E_ALL); ini_set('display_errors', '1'); ini_set('error_log', dirname(__FILE__) . '/e ...
- 一般处理程序如何获取session值
1.要在一般处理程序中获取其他页面的session值,需要引用名空间: using System.Web.SessionState; 2.然后继承一个接口:IRequiresSessionState ...
- alternatives命令用法
alternatives是Linux下的一个功能强大的命令.只能在根权限下执行.如系统中有几个命令功能十分类似,却又不能随意删除,那么可以用替代指定一个全局的设置.alternatives常用于同一个 ...
- 后台树状菜单,js实现递归无限分类
//新闻类别管理 public function new_classify() { $arr = M('news_classify')->where("fid = 0")-& ...
- 使用MyBatis对表执行CRUD操作
一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...