python3通过纯真IP数据库查询IP归属地信息在⽹上看到的别⼈写的python2的代码,修改成了python3。
把纯真IP数据库⽂件qqwry.dat放到czip.py同⼀⽬录下。
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3# filename: czip.py
4
5
6import socket
7import struct
8
9
10class CzIp:
11def__init__(self, db_file='qqwry.dat'):
12 self.f_db = open(db_file, "rb")
13 bs = self.ad(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# _version(), " 纪录总数: %d 条 "%(self.index_count))
20
21def get_version(self):
22'''
23获取版本信息,最后⼀条IP记录 255.255.255.0-255.255.255.255 是版本信息
24 :return: str
25'''
26 s = _addr_by_ip(0xffffff00)
27return s
28
29def _get_area_addr(self, offset=0):
30if offset:
31 self.f_db.seek(offset)
32 bs = self.ad(1)
33 (byte,) = struct.unpack('B', bs)
34if byte == 0x01 or byte == 0x02:
35 p = Long3()
36if p:
_offset_string(p)
38else:
39return""
40else:
41 self.f_db.seek(-1, 1)
_offset_string(offset)
43
44def _get_addr(self, offset):
45'''python怎么读取dat文件
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.ad(1)
54 (byte,) = struct.unpack('B', bs)
55if byte == 0x01: # 重定向模式1
56 country_offset = Long3()
57 self.f_db.seek(country_offset)
58 bs = self.ad(1)
59 (b,) = struct.unpack('B', bs)
60if b == 0x02:
61 country_addr = _offset_Long3())
62 self.f_db.seek(country_offset + 4)
63else:
64 country_addr = _offset_string(country_offset)
65 area_addr = self._get_area_addr()
66elif byte == 0x02: # 重定向模式2
67 country_addr = _offset_Long3())
68 area_addr = self._get_area_addr(offset + 8)
69else: # 字符串模式
70 country_addr = _offset_string(offset + 4)
71 area_addr = self._get_area_addr()
72return country_addr + "" + area_addr
73
74def dump(self, first, last):
75'''
76打印数据库中索引为first到索引为last(不包含last)的记录
77 :param first:
78 :param last:
79 :return:
80'''
81if last > self.index_count:
82 last = self.index_count
83for index in range(first, last):
84 offset = self.first_index + index * 7
85 self.f_db.seek(offset)
86 buf = self.ad(7)
87 (ip, of1, of2) = struct.unpack("IHB", buf)
88 address = self._get_addr(of1 + (of2 << 16))
89print("%d %s %s" % (index, self.ip2str(ip), address)) 90
91def _set_ip_range(self, index):
92 offset = self.first_index + index * 7
93 self.f_db.seek(offset)
94 buf = self.ad(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.ad(4)
99 (self.cur_end_ip,) = struct.unpack("I", buf)
100
101def get_addr_by_ip(self, ip):
102'''
103通过ip查其地址
104 :param ip: (int or str)
105 :return: str
106'''
107if type(ip) == str:
108 ip = self.str2ip(ip)
109 L = 0
110 R = self.index_count - 1
111while L < R - 1:
112 M = int((L + R) / 2)
113 self._set_ip_range(M)
114if ip == self.cur_start_ip:
115 L = M
116break
117if ip > self.cur_start_ip:
118 L = M
119else:
120 R = M
121 self._set_ip_range(L)
122# version information, 255.255.255.X, urgy but useful 123if ip & 0xffffff00 == 0xffffff00:
124 self._set_ip_range(R)
125if self.cur_start_ip <= ip <= self.cur_end_ip:
126 address = self._get_addr(self.cur_end_ip_offset) 127else:
128 address = "未到该IP的地址"
129return address
130
131def get_ip_range(self, ip):
132'''
133返回ip所在记录的IP段
134 :param ip: ip(str or int)
135 :return: str
136'''
137if type(ip) == str:
138 ip = self.str2ip(ip)
139 _addr_by_ip(ip)
140 range = self.ip2str(self.cur_start_ip) + ' - ' \
141 + self.ip2str(self.cur_end_ip)
142return range
143
144def get_offset_string(self, offset=0):
145'''
146获取⽂件偏移处的字符串(以'\0'结尾)
147 :param offset: 偏移
148 :return: str
149'''
150if offset:
151 self.f_db.seek(offset)
152 bs = b''
153 ch = self.ad(1)
154 (byte,) = struct.unpack('B', ch)
155while byte != 0:
156 bs += ch
157 ch = self.ad(1)
158 (byte,) = struct.unpack('B', ch)
159return bs.decode('gbk')
160
161def ip2str(self, ip):
162'''
163整数IP转化为IP字符串
164 :param ip:
165 :return:
166'''
167return str(ip >> 24) + '.' + str((ip >> 16) & 0xff) + '.' + str((ip >> 8) & 0xff) + '.' + str(ip & 0xff) 168
169def str2ip(self, s):
170'''
171 IP字符串转换为整数IP
172 :param s:
173 :return:
174'''
175 (ip,) = struct.unpack('I', socket.inet_aton(s))
176return ((ip >> 24) & 0xff) | ((ip & 0xff) << 24) | ((ip >> 8) & 0xff00) | ((ip & 0xff00) << 8)
177
178def getLong3(self, offset=0):
179'''
180 3字节的数值
181 :param offset:
182 :return:
183'''
184if offset:
185 self.f_db.seek(offset)
186 bs = self.ad(3)
187 (a, b) = struct.unpack('HB', bs)
188return (b << 16) + a
189
190
191
192if__name__ == '__main__':
193 cz = CzIp()
_version())
195 ip = '14.215.177.39'
_ip_range(ip))
_addr_by_ip(ip))
运⾏结果:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论