一、获取最新版IP地址数据库qqwry.dat
纯真IP地址数据库下载地址:http://update.cz88.net/soft/setup.zip
在windows机器上下载解压,点击setup.exe安装,在安装目录下的qqwry.dat即是最新版ip数据库。
也可从51CTO下载(不是最新版,可用于测试):http://down.51cto.com/data/1888530
二、IPLocator.py
网上找到别人用Python写的纯真IP数据库的查询程序,原文地址:http://blog.chinaunix.net/uid-20758462-id-1876988.html,本文对代码做了一些修改,解决中文乱码问题。
建立IPLocator.py文件(见本文附件),内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
#! /usr/bin/env python # -*- coding: utf-8 -*- """ IPLocator: locate IP in the QQWry.dat. Usage:
python IPLocator.py <ip>
""" import socket,string,struct,sys
class IPLocator :
def __init__( self , ipdbFile ):
self .ipdb = open ( ipdbFile, "rb" )
str = self .ipdb.read( 8 )
( self .firstIndex, self .lastIndex) = struct.unpack( 'II' , str )
self .indexCount = ( self .lastIndex - self .firstIndex) / 7 + 1
print self .getVersion(), " 纪录总数: %d 条 " % ( self .indexCount)
def getVersion( self ):
s = self .getIpAddr( 0xffffff00L )
return s
def getAreaAddr( self ,offset = 0 ):
if offset :
self .ipdb.seek( offset )
str = self .ipdb.read( 1 )
(byte,) = struct.unpack( 'B' , str )
if byte = = 0x01 or byte = = 0x02 :
p = self .getLong3()
if p:
return self .getString( p )
else :
return ""
else :
self .ipdb.seek( - 1 , 1 )
return self .getString( offset )
def getAddr( self ,offset,ip = 0 ):
self .ipdb.seek( offset + 4 )
countryAddr = ""
areaAddr = ""
str = self .ipdb.read( 1 )
(byte,) = struct.unpack( 'B' , str )
if byte = = 0x01 :
countryOffset = self .getLong3()
self .ipdb.seek( countryOffset )
str = self .ipdb.read( 1 )
(b,) = struct.unpack( 'B' , str )
if b = = 0x02 :
countryAddr = self .getString( self .getLong3() )
self .ipdb.seek( countryOffset + 4 )
else :
countryAddr = self .getString( countryOffset )
areaAddr = self .getAreaAddr()
elif byte = = 0x02 :
countryAddr = self .getString( self .getLong3() )
areaAddr = self .getAreaAddr( offset + 8 )
else :
countryAddr = self .getString( offset + 4 )
areaAddr = self .getAreaAddr()
return countryAddr + " " + areaAddr
def dump( self , first ,last ):
if last > self .indexCount :
last = self .indexCount
for index in range (first,last):
offset = self .firstIndex + index * 7
self .ipdb.seek( offset )
buf = self .ipdb.read( 7 )
(ip,of1,of2) = struct.unpack( "IHB" ,buf)
address = self .getAddr( of1 + (of2 << 16 ) )
#把GBK转为utf-8
address = unicode (address, 'gbk' ).encode( "utf-8" )
print "%d\t%s\t%s" % (index, self .ip2str(ip), \
address )
def setIpRange( self ,index):
offset = self .firstIndex + index * 7
self .ipdb.seek( offset )
buf = self .ipdb.read( 7 )
( self .curStartIp,of1,of2) = struct.unpack( "IHB" ,buf)
self .curEndIpOffset = of1 + (of2 << 16 )
self .ipdb.seek( self .curEndIpOffset )
buf = self .ipdb.read( 4 )
( self .curEndIp,) = struct.unpack( "I" ,buf)
def getIpAddr( self ,ip):
L = 0
R = self .indexCount - 1
while L < R - 1 :
M = (L + R) / 2
self .setIpRange(M)
if ip = = self .curStartIp:
L = M
break
if ip > self .curStartIp:
L = M
else :
R = M
self .setIpRange( L )
#version information,255.255.255.X,urgy but useful
if ip& 0xffffff00L = = 0xffffff00L :
self .setIpRange( R )
if self .curStartIp < = ip < = self .curEndIp:
address = self .getAddr( self .curEndIpOffset )
#把GBK转为utf-8
address = unicode (address, 'gbk' ).encode( "utf-8" )
else :
address = "未找到该IP的地址"
return address
def getIpRange( self ,ip):
self .getIpAddr(ip)
range = self .ip2str( self .curStartIp) + ' - ' \
+ self .ip2str( self .curEndIp)
return range
def getString( self ,offset = 0 ):
if offset :
self .ipdb.seek( offset )
str = ""
ch = self .ipdb.read( 1 )
(byte,) = struct.unpack( 'B' ,ch)
while byte ! = 0 :
str = str + ch
ch = self .ipdb.read( 1 )
(byte,) = struct.unpack( 'B' ,ch)
return str
def ip2str( self ,ip):
return str (ip>> 24 ) + '.' + str ((ip>> 16 )& 0xffL ) + '.' \
+ str ((ip>> 8 )& 0xffL ) + '.' + str (ip& 0xffL )
def str2ip( self ,s):
(ip,) = struct.unpack( 'I' ,socket.inet_aton(s))
return ((ip>> 24 )& 0xffL )|((ip& 0xffL )<< 24 ) \
|((ip>> 8 )& 0xff00L )|((ip& 0xff00L )<< 8 )
def getLong3( self ,offset = 0 ):
if offset :
self .ipdb.seek( offset )
str = self .ipdb.read( 3 )
(a,b) = struct.unpack( 'HB' , str )
return (b << 16 ) + a
#Demo def main():
IPL = IPLocator( "qqwry.dat" )
ip = ""
if len (sys.argv) ! = 2 :
print 'Usage: python IPLocator.py <IP>'
return
else :
ip = sys.argv[ 1 ]
address = IPL.getIpAddr( IPL.str2ip(ip) )
range = IPL.getIpRange( IPL.str2ip(ip) )
print "此IP %s 属于 %s\n所在网段: %s" % (ip,address, range )
if __name__ = = "__main__" :
main()
|
把qqwry.dat放到和IPLocator.py同一目录,使用方法如下(请参考IPLocator.py中的Demo):
附件:http://down.51cto.com/data/2365189
本文转自 张斌_青岛 51CTO博客,原文链接:http://blog.51cto.com/qicheng0211/1589442