CSDN博客

img d_yang

Python下纯真IP库的乱码问题

发表于2008/10/1 17:17:00  1894人阅读

网上有某位高人写的, 用python去读纯真IP库. 
从库里读出的时候, 有写乱码的情况. 读出的编码是Gb2312的. 
在上面作了一些修改, 主要是把gb2312转为utf-8:


  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """ IPLocator: locate IP in the QQWry.dat.
  4.     Usage:
  5.         python IPLocator.py <ip>
  6.     Create and test with Python 2.2.3.
  7.     spadger@bmy <echo.xjtu@gmail.com> 2008-2-19
  8. """
  9. import socket,string,struct,sys
  10. class IPLocator :
  11.     def __init__( self, ipdbFile ):
  12.         self.ipdb = open( ipdbFile, "rb" )
  13.         str = self.ipdb.read( 8 )
  14.         (self.firstIndex,self.lastIndex) = struct.unpack('II',str)
  15.         self.indexCount = (self.lastIndex - self.firstIndex)/7+1
  16.         print self.getVersion()," 纪录总数: %d 条 "%(self.indexCount)
  17.     def getVersion(self):
  18.         s = self.getIpAddr(0xffffff00L)
  19.         return s
  20.     def getAreaAddr(self,offset=0):
  21.         if offset :
  22.             self.ipdb.seek( offset )
  23.         str = self.ipdb.read( 1 )
  24.         (byte,) = struct.unpack('B',str)
  25.         if byte == 0x01 or byte == 0x02:
  26.             p = self.getLong3()
  27.             if p:
  28.                 return self.getString( p )
  29.             else:
  30.                 return ""
  31.         else:
  32.             self.ipdb.seek(-1,1)
  33.             return self.getString( offset )
  34.     def getAddr(self,offset,ip=0):
  35.         self.ipdb.seek( offset + 4)
  36.         countryAddr = ""
  37.         areaAddr = ""
  38.         str = self.ipdb.read( 1 )
  39.         (byte,) = struct.unpack('B',str)
  40.         if byte == 0x01:
  41.             countryOffset = self.getLong3()
  42.             self.ipdb.seek( countryOffset )
  43.             str = self.ipdb.read( 1 )
  44.             (b,) = struct.unpack('B',str)
  45.             if b == 0x02:
  46.                 countryAddr = self.getString( self.getLong3() )
  47.                 self.ipdb.seek( countryOffset + 4 )
  48.             else:
  49.                 countryAddr = self.getString( countryOffset )
  50.             areaAddr = self.getAreaAddr()
  51.         elif byte == 0x02:
  52.             countryAddr = self.getString( self.getLong3() )
  53.             areaAddr = self.getAreaAddr( offset + 8 )
  54.         else:
  55.             countryAddr = self.getString( offset + 4 )
  56.             areaAddr = self.getAreaAddr()
  57.         return countryAddr + " " + areaAddr
  58.     def dump(self, first ,last ):
  59.         if last > self.indexCount :
  60.             last = self.indexCount
  61.         for index in range(first,last):
  62.             offset = self.firstIndex + index * 7
  63.             self.ipdb.seek( offset )
  64.             buf = self.ipdb.read( 7 )
  65.             (ip,of1,of2) = struct.unpack("IHB",buf)
  66.             print "%d/t%s/t%s" %(index, self.ip2str(ip), /
  67.                 self.getAddr( of1 + (of2 << 16) ) )
  68.     def setIpRange(self,index):
  69.         offset = self.firstIndex + index * 7
  70.         self.ipdb.seek( offset )
  71.         buf = self.ipdb.read( 7 )
  72.         (self.curStartIp,of1,of2) = struct.unpack("IHB",buf)
  73.         self.curEndIpOffset = of1 + (of2 << 16)
  74.         self.ipdb.seek( self.curEndIpOffset )
  75.         buf = self.ipdb.read( 4 )
  76.         (self.curEndIp,) = struct.unpack("I",buf)
  77.     def getIpAddr(self,ip):
  78.         L = 0
  79.         R = self.indexCount - 1
  80.         while L < R-1:
  81.             M = (L + R) / 2
  82.             self.setIpRange(M)
  83.             if ip == self.curStartIp:
  84.                 L = M
  85.                 break
  86.             if ip > self.curStartIp:
  87.                 L = M
  88.             else:
  89.                 R = M
  90.         self.setIpRange( L )
  91.         #version information,255.255.255.X,urgy but useful
  92.         if ip&0xffffff00L == 0xffffff00L:
  93.             self.setIpRange( R )
  94.         if self.curStartIp <= ip <= self.curEndIp:
  95.             address = self.getAddr( self.curEndIpOffset )
  96.             #把GB2312转为utf-8
  97.             address = unicode(address,'gb2312').encode("utf-8")
  98.         else:
  99.             address = "未找到该IP的地址"
  100.         return address
  101.     def getIpRange(self,ip):
  102.         self.getIpAddr(ip)
  103.         range = self.ip2str(self.curStartIp) + ' - ' /
  104.             + self.ip2str(self.curEndIp)
  105.         return range
  106.     def getString(self,offset = 0):
  107.         if offset :
  108.             self.ipdb.seek( offset )
  109.         str = ""
  110.         ch = self.ipdb.read( 1 )
  111.         (byte,) = struct.unpack('B',ch)
  112.         while byte != 0:
  113.             str = str + ch
  114.             ch = self.ipdb.read( 1 )
  115.             (byte,) = struct.unpack('B',ch)
  116.         return str
  117.     def ip2str(self,ip):
  118.         return str(ip>>24)+'.'+str((ip>>16)&0xffL)+'.' /
  119.             +str((ip>>8)&0xffL)+'.'+str(ip&0xffL)
  120.     def str2ip(self,s):
  121.         (ip,) = struct.unpack('L',socket.inet_aton(s))
  122.         return ((ip>>24)&0xffL)|((ip&0xffL)<<24) /
  123.             |((ip>>8)&0xff00L)|((ip&0xff00L)<<8)
  124.     def getLong3(self,offset = 0):
  125.         if offset :
  126.             self.ipdb.seek( offset )
  127.         str = self.ipdb.read(3)
  128.         (a,b) = struct.unpack('HB',str)
  129.         return (b << 16) + a
  130. #Demo
  131. def main():
  132.     IPL = IPLocator( "QQWry.dat" )
  133.     ip = ""
  134.     if len(sys.argv) != 2:
  135.         print 'Usage: python IPLocator.py <IP>'
  136.         return
  137.     else:
  138.         ip = sys.argv[1]
  139.     address = IPL.getIpAddr( IPL.str2ip(ip) )
  140.     range = IPL.getIpRange( IPL.str2ip(ip) )
  141.     print "此IP %s 属于 %s/n所在网段: %s" % (ip,address, range)
  142. if __name__ == "__main__" :
  143.     main()

0 0

相关博文

我的热门文章

img
取 消
img