一、获取最新版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 ):
         =  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 :
             =  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  = =  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):
         =  0
         =  self .indexCount  -  1
         while  L < R - 1 :
             =  (L  +  R)  /  2
             self .setIpRange(M)
             if  ip  = =  self .curStartIp:
                 =  M
                 break
             if  ip >  self .curStartIp:
                 =  M
             else :
                 =  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):

wKiom1SKxheTBaiIAAOTHHV72tE754.jpg