ip地址数据库 高效解析查询
using System;
using System.IO;
using System.Text;
using System.Threading;namespace qqzeng_ip_dat
{/*高性能IP数据库格式详解 qqzeng-ip-ultimate.dat 3.0版 每秒解析1000多万ip编码:UTF8 字节序:Little-Endian 返回多个字段信息(如:亚洲|中国|香港|九龙|油尖旺|新世界电讯|810200|Hong Kong|HK|114.17495|22.327115)------------------------ 文件结构 3.0 -------------------------//文件头 4字节[IP段记录]//前缀区 8字节(4-4) 256*8[索引区start第几个][索引区end第几个] //索引区 8字节(4-3-1) ip段行数*8[结束IP数字][地区流位置][流长度]//内容区 长度无限制[地区信息][地区信息]……唯一不重复------------------------ 文件结构 ---------------------------优势:压缩形式将数据存储在内存中,通过减少将相同数据读取到内存的次数来减少I/O.较高的压缩率通过使用更小的内存中空间提高查询性能。前缀区为作为缩小查询范围,索引区和内容区长度一样,解析出来一次性加载到数组中,查询性能提高3-5倍! 压缩:原版txt为38.5M,生成dat结构为3.68M 。和上一版本2.0不同的是索引区去掉了[开始IP数字]4字节,节省多1-2M。3.0版本只适用[全球版],条件为ip段区间连续且覆盖所有IPV4。2.0版本适用[全球版][国内版][国外版] 性能:每秒解析1000多万ip (环境:CPU i7-7700K + DDR2400 16G + win10 X64)创建:qqzeng-ip 于 2018-04-08*/public class IPSearch3Fast{private static readonly Lazy<IPSearch3Fast> lazy = new Lazy<IPSearch3Fast>(() => new IPSearch3Fast());public static IPSearch3Fast Instance { get { return lazy.Value; } }private IPSearch3Fast(){LoadDat();Watch();}private string datPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"qqzeng-ip-ultimate.dat");private DateTime lastRead = DateTime.MinValue;private long[,] prefmap = new long[256, 2];private uint[] endArr;private string[] addrArr;private byte[] data;/// <summary>/// 初始化二进制 qqzeng-ip-ultimate.dat 数据/// </summary>private void LoadDat(){data = File.ReadAllBytes(datPath);for (int k = 0; k < 256; k++){int i = k * 8 + 4;int prefix = k;long startIndex = ReadLittleEndian32(data[i], data[i + 1], data[i + 2], data[i + 3]);long endIndex = ReadLittleEndian32(data[i + 4], data[i + 5], data[i + 6], data[i + 7]);prefmap[k, 0] = startIndex; prefmap[k, 1] = endIndex;}uint RecordSize = ReadLittleEndian32(data[0], data[1], data[2], data[3]);endArr = new uint[RecordSize];addrArr = new string[RecordSize];for (int i = 0; i < RecordSize; i++){long p = 2052 + (i * 8);uint endipnum = ReadLittleEndian32(data[p], data[1 + p], data[2 + p], data[3 + p]);int offset = data[4 + p] + ((data[5 + p]) << 8) + ((data[6 + p]) << 16);int length = data[7 + p];endArr[i] = endipnum;addrArr[i] = Encoding.UTF8.GetString(data, offset, length);}}private void Watch(){FileInfo fi = new FileInfo(datPath);FileSystemWatcher watcher = new FileSystemWatcher(fi.DirectoryName){IncludeSubdirectories = false,NotifyFilter = NotifyFilters.LastWrite,Filter = "qqzeng-ip-ultimate.dat",};watcher.Changed += (s, e) =>{var lastWriteTime = File.GetLastWriteTime(datPath);if (lastWriteTime > lastRead){ //延时 解决 正由另一进程使用,因此该进程无法访问此文件Thread.Sleep(1000);LoadDat();lastRead = lastWriteTime;}};watcher.EnableRaisingEvents = true;}/// <summary>/// ip快速查询方法/// </summary>/// <param name="ip">1.1.1.1</param>/// <returns></returns>public string Find(string ip){long val = IpToInt(ip, out long pref);long low = prefmap[pref, 0], high = prefmap[pref, 1];long cur = low == high ? low : BinarySearch(low, high, val);return addrArr[cur];}// 二分逼近 O(logN)private long BinarySearch(long low, long high, long k){long M = 0, mid = 0;while (low <= high){mid = (low + high) / 2;uint endipnum = endArr[mid];if (endipnum >= k){M = mid;if (mid == 0){break; //防止溢出}high = mid - 1;}elselow = mid + 1;}return M;}private long IpToInt(string ipString, out long prefix){//高性能int end = ipString.Length;unsafe{fixed (char* name = ipString){int numberBase = 10;char ch;long[] parts = new long[4];long currentValue = 0;int dotCount = 0;int current = 0;for (; current < end; current++){ch = name[current];currentValue = 0;numberBase = 10;if (ch == '0'){numberBase = 8;current++;if (current < end){ch = name[current];if (ch == 'x' || ch == 'X'){numberBase = 16;current++;}}}for (; current < end; current++){ch = name[current];int digitValue;if ((numberBase == 10 || numberBase == 16) && '0' <= ch && ch <= '9'){digitValue = ch - '0';}else if (numberBase == 8 && '0' <= ch && ch <= '7'){digitValue = ch - '0';}else if (numberBase == 16 && 'a' <= ch && ch <= 'f'){digitValue = ch + 10 - 'a';}else if (numberBase == 16 && 'A' <= ch && ch <= 'F'){digitValue = ch + 10 - 'A';}else{break;}currentValue = (currentValue * numberBase) + digitValue;}if (current < end && name[current] == '.'){parts[dotCount] = currentValue;dotCount++;continue;}break;}parts[dotCount] = currentValue;prefix = parts[0];return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);}}//简洁的 普通 //byte[] b = IPAddress.Parse(ip).GetAddressBytes();//prefix = b[0]; // return ReadBigEndian32(b[0], b[1], b[2], b[3]);}private uint ReadBigEndian32(byte a, byte b, byte c, byte d){return (uint)((a << 24) | (b << 16) | (c << 8) | d);}private uint ReadLittleEndian32(byte a, byte b, byte c, byte d){return (uint)(a | (b << 8) | (c << 16) | (d << 24));}}/*(调用例子): string result = IPSearch3Fast.Instance.Find("1.2.3.4");--> result="亚洲|中国|香港|九龙|油尖旺|新世界电讯|810200|Hong Kong|HK|114.17495|22.327115" */
}
ip地址数据库 高效解析查询相关推荐
- 纯真IP地址数据库qqwry.dat解析
ip地址数据库,在现在互联网时代非常有用,比如大型网站的用户安全保护系统,就常常会根据ip反查的信息,甄别账号的一些不安全登录行为,比如跨区域登录问题等.ip其实关联了一些有信息,比如区域,所在运营商 ...
- 最新IP地址数据库 全球IP数据库 国内IP数据库 国外IP数据库 CIDR掩码 2018年1月版...
最新IP地址数据库(qqzeng-ip) 2018年 1月 最新发行版 351756条数据 基于:国内基于省市区以及运营商 国外基于国家 版本: 全球旗舰版 国内精华版 国外拓展版英文版 掩码版 字 ...
- IP地址归属地在线查询平台
一.项目介绍 1.背景 根据IP得到位置,加标签 进行大数据分析,比如淘宝推荐等提供优质数据 www.ip.cn 等 查询IP 2.需求 IP 分析 归属地信息 , 查找在毫秒内完成 IP地址库,公网 ...
- 在 PostgreSQL 中使用码农很忙 IP 地址数据库
在下载到码农很忙 IP 地址数据库后,我们可以将其存储在 PostgreSQL 数据库中,并在需要查询某个 IP 对应的位置数据时,通过 SQL 语句获取正确的结果.这是一种很便捷的使用方式,并且在增 ...
- 在 MySQL 中使用码农很忙 IP 地址数据库
在下载到码农很忙 IP 地址数据库后,我们可以将其存储在 MySQL 数据库中,并在需要查询某个 IP 对应的位置数据时,通过 SQL 语句获取正确的结果.这是一种很便捷的使用方式,并且在增加了恰当的 ...
- PHP读取纯真IP地址数据库
纯真IP地址数据库应该是国内最流行的IP地址数据库 纯真IP地址数据库(官方下载) http://www.cz88.net/fox/ipdat.shtml<?php /*------------ ...
- IP地址数据库 | 手机号段归属地数据库 | 行政区划省市区镇村数据库
2021年4月 最新版 IP地址数据库 (全球版·国内版·国外版·掩码版·英文版) 全球旗舰版 798377行 国内精华版 285113行 演示 https://www.qqzeng.com/i ...
- 最新的IP归属地数据库-最新IP地址数据库
最新IP地址数据库(加微:tcg0531) 2021年 11月 最新发行版 864224条数据 基于:国内基于省市区以及运营商 国外基于国家 大部分城市 运营商 版本: 全球旗舰版 国内精华版 国外拓 ...
- php qqwry.dat_php读取操作IP地址数据库文件QQWry.dat
我们统计流量的时候需要可以获取用户ip,根据用户ip之后可以通过纯ip真数据库QQWry.dat,获取出用户IP 所在的地理位置,这样可以做出更有意义的统计信息. QQWry.dat请自行搜索下载. ...
最新文章
- MySQL触发器的使用
- ubuntu之使用sublime text3搭建Python IDE
- java InputStream的使用
- SAP Spartacus develop branch 的服务器端渲染启动方式
- AD域账户登录mysql_ASP.NET Core AD 域登录
- matlab测量液体液位,基于MATLAB三容水箱液位控制系统.doc
- 接口规范 5. 点播流相关接口
- esxi 需要整合 空间不足_太炫酷了!10月微信新花样!微信情侣空间怎么设置如何弄微信情侣空间在哪里开...
- [Tarjan四连] TarjanLCA
- 高通通过adb一键进入9008端口模式
- JAVA中的二叉树(数据结构)
- 初识Ozone和Segger J-Link Trace Pro
- EDA技术与应用实验二(PowerShell实现)
- imx8qm xen 虚拟网卡
- Linux加密框架中的算法和算法模式(二)
- GIS地理信息系统相关整理
- 音频原始数据能量检测算法
- 解读 ESP32 API参考-system-App Image Format
- 成都速领科技:店铺数据要看哪些
- .net 后端生成海报