根据网上搜索的资料,稍做改动。
from struct import *
import socket
def Ip2Int(ip):
import struct,socket
return struct.unpack("!I",socket.inet_aton(ip))[0]
def Int2Ip(i):
import socket,struct
return socket.inet_ntoa(struct.pack("!I",i))
class IpLook():
def __init__ ( self, fileName ):
self.dataFile = None;
self.head = None;
self.index = [];
self.start( fileName );
def start( self, fileName ):
self.dataFile = open( fileName, 'rb' );
def end( self ):
if self.dataFile:
self.dataFile.close();
def readHead( self):
self.dataFile.seek( 0 );
str = self.dataFile.read( 8 )
self.head = unpack('II', str);
print "head= %d, %d" % self.head
def readIndex( self ):
bytes = self.head[1]-self.head[0] + 7;
count = bytes/7
print "count = ", count
self.dataFile.seek( self.head[0] )
for start in range( 0, count ):
( ip, of1, of2 ) = unpack( 'IHB', self.dataFile.read( 7 ) )
#print ip, of1, of2
#print pack("!I",ip)
self.index.append( ( ip, (of2<<16) + of1 ) )
#self.index.append( ( unpack( 'I', self.dataFile.read( 4 ) ), \
# unpack( 'I', self.dataFile.read( 3 ) ) ))
#print "index===="
#print self.index
#print "index end"
def findIPPoint( self, ip, start, end ):
if( self.index[ start][0] == ip ):
return ( start, self.index[ start][1] )
if( self.index[ end][0] == ip ):
return ( end, self.index[ end][1] )
if( end - start ==1 ):
return ( start, self.index[ start][1] )
middle = (start+end)/2;
if( ip == self.index[ middle ][0] ):
return ( middle, self.index[ middle ][1] )
if( ip < self.index[ middle ][0] ):
return self.findIPPoint( ip, start, middle );
else:
return self.findIPPoint( ip, middle, end );
def findIPAddress( self, ip ):
index, point = self.findIPPoint( ip, 0, len( self.index)-1 );
if point:
self.dataFile.seek( point )
(ip,) = unpack( 'I', self.dataFile.read( 4 ) )
print "find ip =",socket.inet_ntoa( pack('!I', ip ) )
byte = self.dataFile.read( 1 )
if byte == '\x01' :
countryPoint = self.readPoint()
self.dataFile.seek( countryPoint )
byte = self.dataFile.read( 1 )
if byte == '\x02':
countryPoint2 = self.readPoint()
country = self.readString( countryPoint2 )
self.dataFile.seek( countryPoint + 4 )
else:
country = self.readString( countryPoint )
byte = self.dataFile.read( 1 )
if byte == '\x02' or byte == '\x01':
areaPoint = self.readPoint()
area = self.readString( areaPoint )
else:
area = self.readString( countryPoint + len( country) + 1 )
elif byte == '\x02':
countryPoint = self.readPoint()
country = self.readString( countryPoint )
area = self.readString( point + 8 )
else:
country = self.readString( point + 4 );
area = self.readString( point + 4 + len(country) +1 );
return ( Int2Ip( ip ), country, area)
def readPoint( self ):
(offset1, offset2) = unpack( 'HB', self.dataFile.read( 3 ) )
return (offset2<<16) + offset1
def readString( self, offset = 0 ):
self.dataFile.seek( offset )
buffer = [];
byte = self.dataFile.read(1)
while byte != '\x00':
buffer.append( byte )
byte = self.dataFile.read(1);
return "".join(buffer)#.decode( "UTF-8")
if __name__ == "__main__":
look = IpLook( "QQWry.Dat" );
try:
look.readHead( )
look.readIndex()
print look.findIPAddress( Ip2Int( "4.0.0.0" ) )
#except Exception,e:
# pass
finally:
if look :
look.end();
分享到:
相关推荐
总的来说,实现“java读取纯真ip数据库”的过程包括文件I/O操作、数据解析、数据结构选择以及查询接口的设计。通过学习和参考开源项目,我们可以更好地理解和掌握这一技术,从而在实际项目中实现高效的IP地址管理和...
项目中的核心部分是`IPSeeker`模块,它实现了读取IP数据库、解析数据并根据输入的IP地址返回地理位置信息的功能。以下是`IPSeeker`可能包含的关键知识点: 1. **文件读取**:Java的`java.io`包提供了多种读取文件的...
描述还提到了“直接替换掉QQWry.dat就可以更新数据”,这表明该项目使用了一个名为QQWry.dat的特定数据文件来存储IP地址和地理位置信息。当需要更新数据库时,用户只需要替换这个文件,无需更改程序本身,体现了设计...
无论是为LumaQQ这样的客户端程序添加显示IP地址的功能,还是对现有IP数据库进行维护和升级,都要求开发者必须深入理解其文件格式。因此,相关文档和示例(Demo)的存在对于开发者社区而言是极其宝贵的资源。 QQ纯真...
QQwry.dat文件的高效性能,很大程度上依赖于索引区的高效组织结构,使得即使在海量IP数据的情况下,IP查询依然能够保持高效率。这也是为什么像LumaQQ这类应用会采用纯真版的QQwry.dat文件作为其IP查询功能的基础。 ...