Python下纯真IP库的乱码问题

原创 2008年10月01日 17:17:00
网上有某位高人写的, 用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()

解决PHP读取纯真ip数据乱码问题

么会得到的地址将会是乱码,但您可以通过iconv函数转换编码来解决这个问题: $chunzhen_country = iconv(“GB2312″,”UTF-8//IGNORE”,“从纯真得到的地址...
  • zhanghao143lina
  • zhanghao143lina
  • 2016年11月21日 14:29
  • 313

纯真ip数据库UTF-8版2009-08-10

  • 2009年08月21日 15:51
  • 1.73MB
  • 下载

国际化使用UTF-8造成数据库MSSQL Server 2000/2005存储乱码的分析

 看了许多网上使用MSSQL Server 2000/2005使用UTF-8造成数据库存储乱码的描述,也说一下自己做的一个国际化项目的经验。 这个项目描述: 架构:VC++的ATL Server进行开...
  • luzuheng
  • luzuheng
  • 2007年03月23日 14:19
  • 8341

用Python脚本查询纯真IP库QQWry.dat(Demon修改版)

标签: Python, QQWry.dat, 纯真IP 标题: 用Python脚本查询纯真IP库QQWry.dat(Demon修改版) 作者: Demon 链接: http://demo...
  • pi9nc
  • pi9nc
  • 2014年06月23日 16:45
  • 1538

使用php来读取纯真ip数据库

  • testcs_dn
  • testcs_dn
  • 2013年06月14日 10:54
  • 3698

用于提取纯真数据库IP地址列表的python小程序(使用正则表达式)

#conding utf-8 import re,fileinput f=fileinput.input() a='' for i in f: a=a+i myre=re.compile(r...
  • yatere
  • yatere
  • 2011年07月23日 17:20
  • 1815

将纯真ip库转换成普通的文本文件

网络上的IP数据库以纯真版的最为流行,本文不研究格式只给个将其转换为文本格式的代码。关于纯真ip数据库的格式。本文参考了Luma大虾的文章和LumaQQ的IPseeker类的代码,用c语言编写。本...
  • hellwolf
  • hellwolf
  • 2005年07月23日 18:54
  • 3195

python 使用ip库定位IP

# python 示例代码     import os     from ipip import IP     from ipip import IPX     IP...
  • llwh2009714
  • llwh2009714
  • 2017年02月08日 11:58
  • 870

JAVA:实现解析纯真IP数据库

具体解析的纯真版IP地址库请详见http://lumaqq.linuxsir.org/article/qqwry_format_detail.html,这里就不多叙述了。  看下JAVA代码中怎么解...
  • a258831020
  • a258831020
  • 2015年08月05日 16:10
  • 3418

纯真IP数据库导入 MS SQL SERVER

纯真IP 数据库 MS SQL SERVER IPLook
  • china200_ok
  • china200_ok
  • 2017年03月18日 15:25
  • 294
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Python下纯真IP库的乱码问题
举报原因:
原因补充:

(最多只允许输入30个字)