背景
最近公司有个需求,要解析很多行数据,里面有IP地址,让查找深圳和北京的数据,经过上网搜索,发现了很成熟的纯真IP库,可以通过C/Java/Python/PHP等常用编程语言去查询,网上也能找到相应代码。经过对比,Python有函数库可以直接调用查询,最方便。
介绍
纯真自2005年起一直为广大社区用户提供社区版IP地址库,只要获得纯真的授权就能免费使用,并不断获取后续更新的版本。
纯真除了免费的社区版IP库外,还提供数据更加准确、服务更加周全的商业版IP地址查询数据。纯真围绕IP地址,基于 网络空间拓扑测绘 + 移动位置大数据 方案,对IP地址定位、IP网络风险、IP使用场景、IP网络类型、秒拨侦测、VPN侦测、代理侦测、爬虫侦测、真人度等均有近20年丰富的数据沉淀。
可以从官网(https://www.cz88.net/)下载工具,安装后,使用如下:
点解压后,安装目录会有ip_local.txt,这个是各个市的IP段。安装目录有qqwry.dat这个文件,程序就是通过读取这个文件来查询IP。
使用Python代码
from qqwry import QQwry
加载IP库
q = QQwry()
if q.load_file('qqwry.dat')==True:
version = q.get_lastone()
print(u'当前版本:%s,%s' % (version[0],version[1]))
else:
print(u'加载IP库失败')
return False
查询IP
def get_ip_city(q, ip):
'查询纯真IP数据库,返回元组(城市,运营商)'
result = q.lookup(ip)
if result==None:
return u''
return result[0]
IP库分析
参考[https://zhuanlan.zhihu.com/p/360624952]
从上面解压的数据可以了解到,数据库的每条记录有4个部分,分别是起始IP、终止IP、记录A、记录B,前两者构成了一个IP范围,后两者组合起来标记IP段的位置与ISP信息。起始IP与终止IP各占4字节,记录A与记录B不定长,均以字节0结束,数据为GBK编码。
记录A一般为国家、地区名,记录B一般为运营商或者具体位置,不同条目间差异较大且存在不少特殊情况,大多数情况下可将记录A与记录B分别理解为全局部分与局部部分。
一个典型的记录条目如下:
起始IP:42.83.64.0
终止IP:42.83.79.255
记录A:广东省广州市
记录B:电信天翼云计算数据中心
在文件结构上,qqwry.dat 可分为三部分,分别是文件头、记录区和索引区,文件头指出索引区的位置,索引区信息指明记录区的偏移量。
文件头
文件头共8字节,前4字节是第一条索引的绝对偏移,后4字节为最后一条索引的绝对偏移。
文件头标记出索引区的偏移量及包含范围
索引区
索引区由多条等长的索引连续排列而成,每条索引长度为7字节。单条索引由两部分构成,前4个字节为区间的起始IP,后3个字节为其余数据的绝对偏移量,指向记录区的一个位置。
要查找的目标IP必定处于一个IP范围内,而索引区中的起始IP是按从小到大排列的,所以可以根据指定IP匹配到相应的索引,查找到偏移量,并据此到记录区获取其他信息。
记录区
定位到目标索引后可以得到起始IP与偏移量,根据这个偏移量在记录区获取余下的终止IP、记录A和记录B三段信息。
索引中偏移量指向位置的前4字节为终止IP的数据,下方数据部分存放着记录A与记录B两段信息,由于不同IP段之间记录内容存在大量重合,因此文件使用了重定向机制以节省空间,可分为5种存储方式。
记录模式1
这是最简单的一种格式,记录A与记录B在终止IP数据后连续存放,两者均为字符串格式,以二进制0结尾
这种格式不能共用任何记录,一般用于没有重复的数据。
记录模式2
在这种格式下,终止IP后跟有一个重定向标志 0x01,我们暂且称其为重定向模式A。重定向标志后跟随一个偏移量,指明记录A与记录B所在位置,两者在指定的位置连续存放,同样也是字符串格式,以二进制0结尾。
由于正常存储的字符串不会以0x01开头,因此可以与格式1区分开。
记录模式3
这种格式与记录模式2类似,但是只有记录A被重定向,终止IP后跟随重定向标志 0x02,我们暂且称其为重定向模式B。重定向标志后跟随一个偏移量,指出了记录A所在位置,而偏移量后紧接记录B的数据,两条记录均为字符串格式,以二进制0结尾。
两种重定向模式以标志 0x01 与 0x02 作区分,模式A中记录A与记录B是连续存放的,而模式B的重定向仅针对记录A,记录B接在偏移量后面。
与上一种格式一样,正常字符串不会以0x02开头,因此也可以与记录模式1和2区分开。
记录模式4
这种方式需要重定向两次,可以看成重定向模式A与B的叠加。第一次重定向使用标志 0x01,但是偏移量所指位置又出现了重定向标志 0x02,后接的偏移量指出了记录A的内容,偏移量后同时紧跟记录B的数据,两条记录均为字符串格式,以二进制0结尾。
在第一次重定向时,正常字符串不会以0x01开头,因而可以与记录模式2区分开。
记录模式5
这是最繁杂的一种记录方式,可以看成记录模式4的一种扩展。在记录模式4的第二个偏移量后再接一个重定向标志 0x01 或 0x02,标志后有一个偏移量用于指出记录B的位置,不过这个偏移量可能为0,用于表示记录B无数据。同样的,记录A与记录B均为字符串格式,以二进制0结尾。
在对记录B重定向时,正常字符串同样不会以0x01或0x02开头,因此也可以与记录模式4区分开。
特殊记录
数据库的最后一条记录不包含IP信息,而是数据库的版本内容,格式如下:
起始IP:255.255.255.0
终止IP:255.255.255.255
记录A:纯真网络
记录B:XXXX年XX月XX日IP数据
这一部分属于特殊IPv4段 240.0.0.0/4,被标记为 SPECIAL-IPV4-FUTURE-USE-IANA-RESERVED,即IANA特殊保留地址。对于这部分,我们必须对其劫持并返回正确的结果,一般标记为 IANA保留地址。同时,也可以根据这一段信息来提取版本号,格式为 YYYYMMDD,用于标记当前数据库的版本信息。