Python3访问纯真IP数据库的代码
生活随笔
收集整理的這篇文章主要介紹了
Python3访问纯真IP数据库的代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
工作中我們常需要使用純真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数据库的代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 力扣(LeetCode):字符串转换整数
- 下一篇: CNN网络架构演进:从LeNet到Den