设为首页 收藏本站
查看: 933|回复: 0

[经验分享] Python读取纯真IP数据库

[复制链接]

尚未签到

发表于 2018-8-3 12:58:38 | 显示全部楼层 |阅读模式
#! /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()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-545956-1-1.html 上篇帖子: Python 史话 下篇帖子: 教你玩转Python函数和变量
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表