读取纯真IP数据库代码

转载 2006年06月10日 16:23:00

参考文档:http://lumaqq.linuxsir.org/article/qqwry_format_detail.html
作者: gounliey
Email:4473117@qq.com
第一次写东西出来大家分享,还有很多不足之处,请大家指点。

'辅助类,用于保存IP索引信息
Public Class CZ_INDEX_INFO

Public IpSet As UInt32
Public IpEnd As UInt32
Public Offset As UInt32

Sub New()
IpSet = 0
IpEnd = 0
Offset = 0
End Sub

End Class

'读取纯真IP数据库类
Public Class PHCZIP

Protected bFilePathInitialized As Boolean
Protected FilePath As String
Protected FileStrm As FileStream

Protected Index_Set As UInt32
Protected Index_End As UInt32
Protected Index_Count As UInt32

Protected Search_Index_Set As UInt32
Protected Search_Index_End As UInt32
Protected Search_Set As CZ_INDEX_INFO
Protected Search_Mid As CZ_INDEX_INFO
Protected Search_End As CZ_INDEX_INFO

Public Sub New()
bFilePathInitialized = False
End Sub

Public Sub New(ByVal dbFilePath As String)
bFilePathInitialized = False
SetDbFilePath(dbFilePath)
End Sub


'
使用二分法查找索引区,初始化查找区间
Protected Sub Initialize()
Search_Index_Set = 0
Search_Index_End = Index_Count - 1
End Sub

'关闭文件
Public Sub Dispose()
If (bFilePathInitialized) Then
bFilePathInitialized = False
FileStrm.Close()
FileStrm.Dispose()
End If
End Sub

'设置纯真IP数据库的文件路径
Public Function SetDbFilePath(ByVal dbFilePath As String) As Boolean

If (dbFilePath = "") Then
Return False
End If

'Try
'
打开数据文件

FileStrm = New FileStream(dbFilePath, FileMode.Open, FileAccess.Read)
'Catch
'Return False
'End Try

'检查文件长度
If (FileStrm.Length < 8) Then
FileStrm.Close()
FileStrm.Dispose()
Return False
End If

'得到第一条索引的绝对偏移和最后一条索引的绝对偏移
FileStrm.Seek(0, SeekOrigin.Begin)

Index_Set = GetUInt32()
Index_End = GetUInt32()

'得到总索引条数
Index_Count = (Index_End - Index_Set) / 7 + 1
bFilePathInitialized = True

Return True

End Function

'主接口函数,根据传入的IP返回该IP的地址信息
Public Function GetAddressWithIP(ByVal IPvalue As String) As String

If Not bFilePathInitialized Then
Return ""
End If

Initialize()

'IP转化为数字
Dim ip As UInt32 = IPToUInt32(IPvalue)

While (True)

'首先初始化本轮查找的区间

'区间头
Search_Set = IndexInfoAtPos(Search_Index_Set)
'
区间尾
Search_End = IndexInfoAtPos(Search_Index_End)

'判断IP是否在区间头内
If (ip >= Search_Set.IpSet And ip <= Search_Set.IpEnd) Then
Return ReadAddressInfoAtOffset(Search_Set.Offset)
End If

'判断IP是否在区间尾内
If (ip >= Search_End.IpSet And ip <= Search_End.IpEnd) Then
Return ReadAddressInfoAtOffset(Search_End.Offset)
End If

'计算出区间中点
Search_Mid = IndexInfoAtPos((Search_Index_End + Search_Index_Set) / 2)

'判断IP是否在中点
If (ip >= Search_Mid.IpSet And ip <= Search_Mid.IpEnd) Then
Return ReadAddressInfoAtOffset(Search_Mid.Offset)
End If

'本轮没有找到,准备下一轮
If (ip < Search_Mid.IpSet) Then
'IP
比区间中点要小,将区间尾设为现在的中点,将区间缩小1倍。
Search_Index_End = (Search_Index_End + Search_Index_Set) / 2
Else
'IP
比区间中点要大,将区间头设为现在的中点,将区间缩小1倍。
Search_Index_Set = (Search_Index_End + Search_Index_Set) / 2
End If

End While

Return ""

End Function

'读取指定文件偏移位置的国家和地区信息
Protected Function ReadAddressInfoAtOffset(ByVal Offset As UInt32) As String

Dim country As String = ""
Dim area As String = ""
Dim country_Offset As UInt32 = 0
Dim Tag As Byte = 0
'
跳过4字节,因这4个字节是该索引的IP区间上限。
FileStrm.Seek(Offset + 4, SeekOrigin.Begin)

'读取一个字节,得到描述国家信息的寻址方式
Tag = GetTag()

If (Tag = &H1) Then

'模式0x01,表示接下来的3个字节是表示偏移位置
FileStrm.Seek(GetOffset(), SeekOrigin.Begin)

'继续检查寻址方式
Tag = GetTag()
If (Tag = &H2) Then
'
模式0x02,表示接下来的3个字节代表国家信息的偏移位置
'
先将这个偏移位置保存起来,因为我们要读取它后面的地区信息。
country_Offset = GetOffset()
'
读取地区信息(注:按照Luma的说明,好像没有这么多种可能性,但在测试过程中好像有些情况没有考虑到,
'
所以写了个ReadArea()来读取。
area = ReadArea()
'
读取国家信息
FileStrm.Seek(country_Offset, SeekOrigin.Begin)
country = ReadString()

Else
'
这种模式说明接下来就是保存的国家和地区信息了,以'/0'代表结束。
FileStrm.Seek(-1, SeekOrigin.Current)
country = ReadString()
area = ReadArea()

End If

ElseIf (Tag = &H2) Then
'
模式0x02,说明国家信息是一个偏移位置
country_Offset = GetOffset()
'
先读取地区信息
area = ReadArea()
'
读取国家信息
FileStrm.Seek(country_Offset, SeekOrigin.Begin)
country = ReadString()

Else
'
这种模式最简单了,直接读取国家和地区就OK
FileStrm.Seek(-1, SeekOrigin.Current)
country = ReadString()
area = ReadArea()

End If

Return country + " " + area

End Function

'从当前位置读取一个字符串(国家或者地区信息)
Protected Function ReadString() As String

Dim Offset As UInt32 = 0
Dim TempByteArray(256) As Byte
TempByteArray(Offset) = FileStrm.ReadByte()
While (TempByteArray(Offset) <> &H0)
Offset += 1
TempByteArray(Offset) = FileStrm.ReadByte()
End While

Return System.Text.Encoding.Default.GetString(TempByteArray)

End Function

'从当前文件位置读取地区信息
Protected Function ReadArea() As String

Dim Tag As Byte = GetTag()

If (Tag = &H1 Or Tag = &H2) Then
FileStrm.Seek(GetOffset(), SeekOrigin.Begin)
Return ReadString()
Else
FileStrm.Seek(-1, SeekOrigin.Current)
Return ReadString()
End If

End Function

'从当前文件位置读取一个字节的标识
Protected Function GetTag() As Byte
Return FileStrm.ReadByte()
End Function

'得到指定索引位置的信息(IP起始范围)
Protected Function IndexInfoAtPos(ByVal Index_Pos As Int32) As CZ_INDEX_INFO

Dim Index_Info As New CZ_INDEX_INFO
'
根据索引编号计算出在文件中在偏移位置
FileStrm.Seek(Index_Set + 7 * Index_Pos, SeekOrigin.Begin)
Index_Info.IpSet = GetUInt32()
Index_Info.Offset = GetOffset()
FileStrm.Seek(Index_Info.Offset, SeekOrigin.Begin)
Index_Info.IpEnd = GetUInt32()

Return Index_Info

End Function

'读取3个字节,得到偏移位置
Protected Function GetOffset() As UInt32

Dim TempByte4(4) As Byte
TempByte4(0) = FileStrm.ReadByte()
TempByte4(1) = FileStrm.ReadByte()
TempByte4(2) = FileStrm.ReadByte()
TempByte4(3) = 0
Return BitConverter.ToUInt32(TempByte4, 0)

End Function

Protected Function GetUInt32() As UInt32

Dim TempByte4(4) As Byte
FileStrm.Read(TempByte4, 0, 4)
Return BitConverter.ToUInt32(TempByte4, 0)

End Function


'
将字符串的IP转换成Int32
Public Shared Function IPToUInt32(ByVal Ipvalue As String) As UInt32

Dim IpByte() As String = Ipvalue.Split(".")
Dim nUpperBound As Int32 = IpByte.GetUpperBound(0)
If nUpperBound <> 3 Then
ReDim Preserve IpByte(4)
For i As Int32 = 1 To 3 - nUpperBound
IpByte(nUpperBound + i) = "0"
Next
End If

Dim TempByte4(4) As Byte
For i As Int32 = 0 To 3
'
如果是.Net 2.0可以支持TryParse
'If Not (Byte.TryParse(IpByte(i), TempByte4(3 - i))) Then
'TempByte4(3 - i) = &H0
'End If
If (IsNumeric(IpByte(i))) Then
TempByte4(3 - i) = CInt(IpByte(i)) And &HFF
End If
Next

Return BitConverter.ToUInt32(TempByte4, 0)
'System.Net.IPAddress.NetworkToHostOrder

End Function

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

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

C#读取纯真IP数据库的代码

 C#读取纯真IP数据库的代码 /// /// PHCZIP 的摘要说明。/// ///     (转自http://community.csdn.net/Expert/topic/5325/5325...
  • xingkongmanbu
  • xingkongmanbu
  • 2007年04月06日 18:39
  • 481

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

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

PHP利用纯真IP数据库在本地实现IP地址信息查询

准备工作: 建议本地IP地址数据库,请到http://www.cz88.net/这个网站下载一个纯真IP数据库,安装完成后,到安装目录里把QQWry.dat文件取出来,这个就是我们想要的IP数据...
  • myweishanli
  • myweishanli
  • 2015年04月17日 16:30
  • 2355

java读取纯真IP数据库qqwry.dat的源代码

java读取纯真IP数据库QQwry.dat的源代码,要运行此程序必须有到网上下载QQwry.dat,下载地址 http://www.cz88.net/down/   由于太大,我这里就不提供了。 ...
  • syc001
  • syc001
  • 2017年06月02日 10:10
  • 3566

纯真IP数据库导入 MS SQL SERVER

纯真IP 数据库 MS SQL SERVER IPLook
  • china200_ok
  • china200_ok
  • 2017年03月18日 15:25
  • 298

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

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

java解析纯真IP数据库,查询IP,导出所有数据,插入oracle

机缘巧合之下,需要研究下IP数据库,这个库提供给的IP定位功能十分之有用。 可以想象,他会被用在很多场合,电子商务需要统计网站流量的来源和分布,社交工具可以知道对方所在的位置等等;、     网...
  • qq_27289001
  • qq_27289001
  • 2016年05月17日 08:39
  • 296

利用纯真IP库建立mysql ip数据库

首先到http://www.cz88.net/  下载一个最新的ip库,安装ip库后会生成一个快捷方式,如下图所示: 点击打开后,出现下图界面: 点击解压,会生成一个20多...
  • maochencw
  • maochencw
  • 2012年01月05日 16:16
  • 6832

一个类似纯真IP数据库的存储和读取程序

一个类似纯真IP数据库的存储和读取程序  ,删除了国外的IP数据,国内只到省市一级 如:192.168.1.2  ,192.168.2.155 福建省 厦门市  writeerror_reportin...
  • jun54555
  • jun54555
  • 2009年05月22日 23:17
  • 516
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:读取纯真IP数据库代码
举报原因:
原因补充:

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