工作中我们常需要使用纯真IP数据库内的数据做分析,如何使用Python3访问读取纯真IP数据库的方法有很多朋友需要。今天在网上找了一个,分享一下。虽然不知道该代码的作者是谁,顺便感谢一下~~~

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# filename: czip.pyimport socket
import structclass CzIp:def __init__(self, db_file='qqwry.dat'):self.f_db = open(db_file, "rb")bs = self.f_db.read(8)(self.first_index, self.last_index) = struct.unpack('II', bs)self.index_count = int((self.last_index - self.first_index) / 7 + 1)self.cur_start_ip = Noneself.cur_end_ip_offset = Noneself.cur_end_ip = None# print(self.get_version(), " 记录总数: %d 条 "%(self.index_count))def get_version(self):'''获取版本信息,最后一条IP记录 255.255.255.0-255.255.255.255 是版本信息:return: str'''s = self.get_addr_by_ip(0xffffff00)return sdef _get_area_addr(self, offset=0):if offset:self.f_db.seek(offset)bs = self.f_db.read(1)(byte,) = struct.unpack('B', bs)if byte == 0x01 or byte == 0x02:p = self.getLong3()if p:return self.get_offset_string(p)else:return ""else:self.f_db.seek(-1, 1)return self.get_offset_string(offset)def _get_addr(self, offset):'''获取offset处记录区地址信息(包含国家和地区)如果是中国ip,则是 "xx省xx市 xxxxx地区" 这样的形式(比如:"福建省 电信", "澳大利亚 墨尔本Goldenit有限公司"):param offset::return:str'''self.f_db.seek(offset + 4)bs = self.f_db.read(1)(byte,) = struct.unpack('B', bs)if byte == 0x01:    # 重定向模式1country_offset = self.getLong3()self.f_db.seek(country_offset)bs = self.f_db.read(1)(b,) = struct.unpack('B', bs)if b == 0x02:   country_addr = self.get_offset_string(self.getLong3())self.f_db.seek(country_offset + 4)else:   country_addr = self.get_offset_string(country_offset)area_addr = self._get_area_addr()elif byte == 0x02:  # 重定向模式2country_addr = self.get_offset_string(self.getLong3())area_addr = self._get_area_addr(offset + 8)else:   # 字符串模式country_addr = self.get_offset_string(offset + 4)area_addr = self._get_area_addr()return country_addr + " " + area_addrdef dump(self, first, last):'''打印数据库中索引为first到索引为last(不包含last)的记录:param first::param last::return:'''if last > self.index_count:last = self.index_countfor index in range(first, last):offset = self.first_index + index * 7self.f_db.seek(offset)buf = self.f_db.read(7)(ip, of1, of2) = struct.unpack("IHB", buf)address = self._get_addr(of1 + (of2 << 16))print("%d %s %s" % (index, self.ip2str(ip), address))def _set_ip_range(self, index):offset = self.first_index + index * 7self.f_db.seek(offset)buf = self.f_db.read(7)(self.cur_start_ip, of1, of2) = struct.unpack("IHB", buf)self.cur_end_ip_offset = of1 + (of2 << 16)self.f_db.seek(self.cur_end_ip_offset)buf = self.f_db.read(4)(self.cur_end_ip,) = struct.unpack("I", buf)def get_addr_by_ip(self, ip):'''通过ip查找其地址:param ip: (int or str):return: str'''if type(ip) == str:ip = self.str2ip(ip)L = 0R = self.index_count - 1while L < R - 1:M = int((L + R) / 2)self._set_ip_range(M)if ip == self.cur_start_ip:L = Mbreakif ip > self.cur_start_ip:L = Melse:R = Mself._set_ip_range(L)# version information, 255.255.255.X, urgy but usefulif ip & 0xffffff00 == 0xffffff00:self._set_ip_range(R)if self.cur_start_ip <= ip <= self.cur_end_ip:address = self._get_addr(self.cur_end_ip_offset)else:address = "未找到该IP的地址"return addressdef get_ip_range(self, ip):'''返回ip所在记录的IP段:param ip: ip(str or int):return: str'''if type(ip) == str:ip = self.str2ip(ip)self.get_addr_by_ip(ip)range = self.ip2str(self.cur_start_ip) + ' - ' \+ self.ip2str(self.cur_end_ip)return rangedef get_offset_string(self, offset=0):'''获取文件偏移处的字符串(以'\0'结尾):param offset: 偏移:return: str'''if offset:self.f_db.seek(offset)bs = b''ch = self.f_db.read(1)(byte,) = struct.unpack('B', ch)while byte != 0:bs += chch = self.f_db.read(1)(byte,) = struct.unpack('B', ch)return bs.decode('gbk')def ip2str(self, ip):'''整数IP转化为IP字符串:param ip::return:'''return str(ip >> 24) + '.' + str((ip >> 16) & 0xff) + '.' + str((ip >> 8) & 0xff) + '.' + str(ip & 0xff)def str2ip(self, s):'''IP字符串转换为整数IP:param s::return:'''(ip,) = struct.unpack('I', socket.inet_aton(s))return ((ip >> 24) & 0xff) | ((ip & 0xff) << 24) | ((ip >> 8) & 0xff00) | ((ip & 0xff00) << 8)def getLong3(self, offset=0):'''3字节的数值:param offset::return:'''if offset:self.f_db.seek(offset)bs = self.f_db.read(3)(a, b) = struct.unpack('HB', bs)return (b << 16) + aif __name__ == '__main__':cz = CzIp()print(cz.get_version())ip = '8.8.8.8'print(cz.get_ip_range(ip))print(cz.get_addr_by_ip(ip))

运行结果如下:

纯真网络 2019年8月30日IP数据
8.8.8.8 - 8.8.8.8
美国 加利福尼亚州圣克拉拉县山景市谷歌公司DNS服务器
[Finished in 0.1s]

Python3访问纯真IP数据库的代码相关推荐

  1. 读取纯真IP数据库的公用组件QQWry.NET

    这是一个读取纯真IP数据库的公用组件接口,我是通过luma的<纯真IP数据库格式详解>了解了纯真IP数据库数据格式,并且基于网络上的一个IPLocation.dll源码的基础改编而来.我为 ...

  2. 纯真IP数据库格式详解

    摘要 网络上的IP数据库以纯真版的最为流行,LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础.不过关于其格式的文档却非常之少,后来终于在网上 找到了一份文档,得以了解其内幕,不过那份文档寥寥 ...

  3. php 读取纯真书库,PHP读取纯真IP数据库的函数

    PHP读取纯真IP数据库的函数,以下代码提取自Discuz! X2 $tinyipfile Discuz! 独有高压缩比算法和快速检索的IP数据库路径 下载地址:http://www.discuz.n ...

  4. java读取纯真IP数据库qqwry.dat的源代码

    java读取纯真IP数据库QQwry.dat的源代码,要运行此程序必须有 到网上下载QQwry.dat,下载地址 http://www.cz88.net/down/   由于太大,我这里就不提供了. ...

  5. 纯真IP数据库格式详解zt

    摘要 网络上的IP数据库以纯真版的最为流行,LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础.不过关于其格式的文档却非常之少,后来终于在网上找到了一份文档,得以了解其内幕,不过那份文档寥寥数 ...

  6. php获取ip 然后返回地址,PHP调用纯真IP数据库返回具体地址的方法

    我们在日常开发中友很多场景需要显示具体的IP地址,如果调用本地的IP的地址库,这就需要考虑IP地址库数据量的问题,所以我们一般会采用在线的IP地址查询,今天就把PHP如何调用本地的纯真IP地址数据的教 ...

  7. [转]纯真IP数据库格式详解

    纯真IP数据库格式详解 摘要 网络上的IP数据库以纯真版的最为流行,LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础.不过关于其格式的文档却非常之少,后来终于在网上找到了一份文档,得以了解其 ...

  8. 为PHP增加纯真IP数据库(qqwry)支持https://blog.jiqila.com/post/229/

    当我们的网站需要根据IP来查询IP来源时,我们需要一个IP数据库,而国内最好的IP数据库当属"纯真IP数据库"了.为了读取"纯真IP数据库"中的数据,一般情况下 ...

  9. 纯真IP数据库(qqwry.dat)转换成最新的IP数据库格式(ipwry.dat)

    转载自:http://blog.cafeboy.org/2011/02/25/qqwry-to-ipwry/ http://blog.csdn.net/cnss/article/details/136 ...

最新文章

  1. 在网页中使用react
  2. mysql 5.5 查询_mysql5.5数据库优化--定位慢查询
  3. java dragged_Java:mouseDragged并在图形界面中移动
  4. 设计模式--单例模式--Java实现
  5. 2019日历全年一张_看,日历里居然藏着一座艺术馆!让这本最美日历开启2021年好运...
  6. html中logo不变形,CSS3如何实现LOGO中的文本变形动画
  7. 三周第二次课(4月3日)
  8. 在NVME SSD上安装WIN7
  9. VGA、HDMI、DVI 和 DP接口
  10. PS4蓝牙手柄分析之1
  11. Java传输文件使用Base64优化传输速率。
  12. 基于CANoe的ECU Bootloader刷写软件
  13. Codeforces 731C Socks By Assassin
  14. Grasshopper脚本电池处理全站仪数据,生成建筑、线状地物和地形
  15. 微信小程序接受服务器发过来的消息,微信小程序API 接收消息和事件
  16. Bootstrap系列之纵向对齐(Vertical alignment)
  17. MySQL学习笔记(5)
  18. CentOS 7下安装Redis
  19. 如何在Outlook中单击邮件后立即将其标记为已读
  20. Kubernetes(K8S)(六)——service(ClusterIP、NodePort、无头服务、LoadBalancer、ExternalName等)

热门文章

  1. 小雷郑重承诺:在2017年之前,对大学毕业4年以来的所有努力和探索,做一个全面客观的总结,技术研究、工作创业、投资理财、朋友感情等...
  2. 【MongoDB】嵌套数组查询方案
  3. Linux监控平台 zabbix介绍和安装
  4. CopyOnWriteArrayList源码分析
  5. 云监控服务产品优势与应用场景
  6. 20172304 结对编程--四则运算实验总结
  7. windows10安装Oracle提示错误-INS-13001环境不满足最低要求
  8. iOS: JS和Native交互的两种方法,iosjsnative交互
  9. RedHat/CentOS系统信息查看命令大全
  10. [转]浅谈:国内软件公司为何无法做大做强