在网上看到的别人写的python2的代码,修改成了python3。
把纯真IP数据库文件qqwry.dat放到czip.py同一目录下。
1 #! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # filename: czip.py 4 5 6 import socket 7 import struct 8 9 10 class CzIp: 11 def __init__(self, db_file='qqwry.dat'): 12 self.f_db = open(db_file, "rb") 13 bs = self.f_db.read(8) 14 (self.first_index, self.last_index) = struct.unpack('II', bs) 15 self.index_count = int((self.last_index - self.first_index) / 7 + 1) 16 self.cur_start_ip = None 17 self.cur_end_ip_offset = None 18 self.cur_end_ip = None 19 # print(self.get_version(), " 纪录总数: %d 条 "%(self.index_count)) 20 21 def get_version(self): 22 ''' 23 获取版本信息,最后一条IP记录 255.255.255.0-255.255.255.255 是版本信息 24 :return: str 25 ''' 26 s = self.get_addr_by_ip(0xffffff00) 27 return s 28 29 def _get_area_addr(self, offset=0): 30 if offset: 31 self.f_db.seek(offset) 32 bs = self.f_db.read(1) 33 (byte,) = struct.unpack('B', bs) 34 if byte == 0x01 or byte == 0x02: 35 p = self.getLong3() 36 if p: 37 return self.get_offset_string(p) 38 else: 39 return "" 40 else: 41 self.f_db.seek(-1, 1) 42 return self.get_offset_string(offset) 43 44 def _get_addr(self, offset): 45 ''' 46 获取offset处记录区地址信息(包含国家和地区) 47 如果是中国ip,则是 "xx省xx市 xxxxx地区" 这样的形式 48 (比如:"福建省 电信", "澳大利亚 墨尔本Goldenit有限公司") 49 :param offset: 50 :return:str 51 ''' 52 self.f_db.seek(offset + 4) 53 bs = self.f_db.read(1) 54 (byte,) = struct.unpack('B', bs) 55 if byte == 0x01: # 重定向模式1 56 country_offset = self.getLong3() 57 self.f_db.seek(country_offset) 58 bs = self.f_db.read(1) 59 (b,) = struct.unpack('B', bs) 60 if b == 0x02: 61 country_addr = self.get_offset_string(self.getLong3()) 62 self.f_db.seek(country_offset + 4) 63 else: 64 country_addr = self.get_offset_string(country_offset) 65 area_addr = self._get_area_addr() 66 elif byte == 0x02: # 重定向模式2 67 country_addr = self.get_offset_string(self.getLong3()) 68 area_addr = self._get_area_addr(offset + 8) 69 else: # 字符串模式 70 country_addr = self.get_offset_string(offset + 4) 71 area_addr = self._get_area_addr() 72 return country_addr + " " + area_addr 73 74 def dump(self, first, last): 75 ''' 76 打印数据库中索引为first到索引为last(不包含last)的记录 77 :param first: 78 :param last: 79 :return: 80 ''' 81 if last > self.index_count: 82 last = self.index_count 83 for index in range(first, last): 84 offset = self.first_index + index * 7 85 self.f_db.seek(offset) 86 buf = self.f_db.read(7) 87 (ip, of1, of2) = struct.unpack("IHB", buf) 88 address = self._get_addr(of1 + (of2 << 16)) 89 print("%d %s %s" % (index, self.ip2str(ip), address)) 90 91 def _set_ip_range(self, index): 92 offset = self.first_index + index * 7 93 self.f_db.seek(offset) 94 buf = self.f_db.read(7) 95 (self.cur_start_ip, of1, of2) = struct.unpack("IHB", buf) 96 self.cur_end_ip_offset = of1 + (of2 << 16) 97 self.f_db.seek(self.cur_end_ip_offset) 98 buf = self.f_db.read(4) 99 (self.cur_end_ip,) = struct.unpack("I", buf) 100 101 def get_addr_by_ip(self, ip): 102 ''' 103 通过ip查找其地址 104 :param ip: (int or str) 105 :return: str 106 ''' 107 if type(ip) == str: 108 ip = self.str2ip(ip) 109 L = 0 110 R = self.index_count - 1 111 while L <