VS.NET讀取純真IP數(shù)據(jù)庫(kù)(VB)

2010-08-28 10:50:35來(lái)源:西部e網(wǎng)作者:

'參考文檔:http://lumaqq.linuxsir.org/article/qqwry_format_detail.html
'作者: gounliey
'Email:4473117@qq.com

'第一次寫(xiě)東西出來(lái)大家分享,還有很多不足之處,請(qǐng)大家指點(diǎn)。

'輔助類,用于保存IP索引信息
Public Class CZ_INDEX_INFO

Public IpSet As UInt32
,ublic IpEnd As UInt32
,ublic Offset As UInt32

Sub New()
,,,pSet = 0
,,,pEnd = 0
,,,ffset = 0
,nd Sub

End Class

'讀取純真IP數(shù)據(jù)庫(kù)類
Public Class PHCZIP

Protected bFilePathInitialized As Boolean
,rotected FilePath As String
Protected FileStrm As FileStream

,rotected Index_Set As UInt32
Protected Index_End As UInt32
,rotected Index_Count As UInt32

,rotected Search_Index_Set As UInt32
Protected Search_Index_End As UInt32
,rotected Search_Set As CZ_INDEX_INFO
,rotected Search_Mid As CZ_INDEX_INFO
Protected Search_End As CZ_INDEX_INFO

,ublic Sub New()
,FilePathInitialized = False
End Sub

,ublic Sub New(ByVal dbFilePath As String)
,,FilePathInitialized = False
,,,etDbFilePath(dbFilePath)
,nd Sub


,'使用二分法查找索引區(qū),初始化查找區(qū)間
,rotected Sub Initialize()
,,,earch_Index_Set = 0
,,,earch_Index_End = Index_Count - 1
,nd Sub

,'關(guān)閉文件
,ublic Sub Dispose()
,,f (bFilePathInitialized) Then
,,,,FilePathInitialized = False
,,,,,ileStrm.Close()
,,,,,ileStrm.Dispose()
,,,nd If
,nd Sub

,'設(shè)置純真IP數(shù)據(jù)庫(kù)的文件路徑
,ublic Function SetDbFilePath(ByVal dbFilePath As String) As Boolean

,,f (dbFilePath = "") Then
,,,,,eturn False
,,,nd If

,,,'Try
,,,'打開(kāi)數(shù)據(jù)文件

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

,,,'檢查文件長(zhǎng)度
,,f (FileStrm.Length < 8) Then
,,,,ileStrm.Close()
,,,,ileStrm.Dispose()
,,,,eturn False
,,,nd If

,,'得到第一條索引的絕對(duì)偏移和最后一條索引的絕對(duì)偏移
,,,ileStrm.Seek(0, SeekOrigin.Begin)

,,,ndex_Set = GetUInt32()
,,ndex_End = GetUInt32()

,,,'得到總索引條數(shù)
,,ndex_Count = (Index_End - Index_Set) / 7 + 1
,,,FilePathInitialized = True

,,,eturn True

,nd Function

,'主接口函數(shù),根據(jù)傳入的IP返回該IP的地址信息
,ublic Function GetAddressWithIP(ByVal IPvalue As String) As String

,,,f Not bFilePathInitialized Then
,,,,,eturn ""
,,,nd If

,,,nitialize()

,,,'將IP轉(zhuǎn)化為數(shù)字
,,im ip As UInt32 = IPToUInt32(IPvalue)

,,,hile (True)

,,,,'首先初始化本輪查找的區(qū)間

,,,,,'區(qū)間頭
,,,,,earch_Set = IndexInfoAtPos(Search_Index_Set)
,,,,,'區(qū)間尾
,,,,,earch_End = IndexInfoAtPos(Search_Index_End)

,,,,,'判斷IP是否在區(qū)間頭內(nèi)
,,,,,f (ip >= Search_Set.IpSet And ip <= Search_Set.IpEnd) Then
,,,,,,,eturn ReadAddressInfoAtOffset(Search_Set.Offset)
,,,,,nd If

,,,,,'判斷IP是否在區(qū)間尾內(nèi)
,,,,f (ip >= Search_End.IpSet And ip <= Search_End.IpEnd) Then
,,,,,,eturn ReadAddressInfoAtOffset(Search_End.Offset)
,,,,,nd If

,,,,'計(jì)算出區(qū)間中點(diǎn)
,,,,earch_Mid = IndexInfoAtPos((Search_Index_End + Search_Index_Set) / 2)

,,,,'判斷IP是否在中點(diǎn)
,,,,,f (ip >= Search_Mid.IpSet And ip <= Search_Mid.IpEnd) Then
,,,,,,,eturn ReadAddressInfoAtOffset(Search_Mid.Offset)
,,,,nd If

,,,,,'本輪沒(méi)有找到,準(zhǔn)備下一輪
,,,,,f (ip < Search_Mid.IpSet) Then
,,,,,,,'IP比區(qū)間中點(diǎn)要小,將區(qū)間尾設(shè)為現(xiàn)在的中點(diǎn),將區(qū)間縮小1倍。
,,,,,,,earch_Index_End = (Search_Index_End + Search_Index_Set) / 2
,,,,,lse
,,,,,,,'IP比區(qū)間中點(diǎn)要大,將區(qū)間頭設(shè)為現(xiàn)在的中點(diǎn),將區(qū)間縮小1倍。
,,,,,,,earch_Index_Set = (Search_Index_End + Search_Index_Set) / 2
,,,,,nd If

,,,nd While

,,,eturn ""

,nd Function

'讀取指定文件偏移位置的國(guó)家和地區(qū)信息
Protected Function ReadAddressInfoAtOffset(ByVal Offset As UInt32) As String

,,,im country As String = ""
,,im area As String = ""
,,im country_Offset As UInt32 = 0
,,im Tag As Byte = 0
,,,'跳過(guò)4字節(jié),因這4個(gè)字節(jié)是該索引的IP區(qū)間上限。
,,,ileStrm.Seek(Offset + 4, SeekOrigin.Begin)

,,,'讀取一個(gè)字節(jié),得到描述國(guó)家信息的“尋址方式”
,,,ag = GetTag()

,,,f (Tag = &H1) Then

,,,,,'模式0x01,表示接下來(lái)的3個(gè)字節(jié)是表示偏移位置
,,,,,ileStrm.Seek(GetOffset(), SeekOrigin.Begin)

,,,,'繼續(xù)檢查“尋址方式”
,,,,,ag = GetTag()
,,,,,f (Tag = &H2) Then
,,,,,,,'模式0x02,表示接下來(lái)的3個(gè)字節(jié)代表國(guó)家信息的偏移位置
,,,,,,,'先將這個(gè)偏移位置保存起來(lái),因?yàn)槲覀円x取它后面的地區(qū)信息。
,,,,,,ountry_Offset = GetOffset()
,,,,,,,'讀取地區(qū)信息(注:按照Luma的說(shuō)明,好像沒(méi)有這么多種可能性,但在測(cè)試過(guò)程中好像有些情況沒(méi)有考慮到,
,,,,,,,'所以寫(xiě)了個(gè)ReadArea()來(lái)讀取。
,,,,,,,rea = ReadArea()
,,,,,,,'讀取國(guó)家信息
,,,,,,ileStrm.Seek(country_Offset, SeekOrigin.Begin)
,,,,,,,ountry = ReadString()

,,,,,lse
,,,,,,,'這種模式說(shuō)明接下來(lái)就是保存的國(guó)家和地區(qū)信息了,以'\0'代表結(jié)束。
,,,,,,,ileStrm.Seek(-1, SeekOrigin.Current)
,,,,,,,ountry = ReadString()
,,,,,,,rea = ReadArea()

,,,,,nd If

,,,lseIf (Tag = &H2) Then
,,,,'模式0x02,說(shuō)明國(guó)家信息是一個(gè)偏移位置
,,,,,ountry_Offset = GetOffset()
,,,,'先讀取地區(qū)信息
,,,,,rea = ReadArea()
,,,,,'讀取國(guó)家信息
,,,,,ileStrm.Seek(country_Offset, SeekOrigin.Begin)
,,,,ountry = ReadString()

,,,lse
,,,,'這種模式最簡(jiǎn)單了,直接讀取國(guó)家和地區(qū)就OK了
,,,,ileStrm.Seek(-1, SeekOrigin.Current)
,,,,ountry = ReadString()
,,,,,rea = ReadArea()

,,,nd If

,,eturn country + " " + area

,nd Function

'從當(dāng)前位置讀取一個(gè)字符串(國(guó)家或者地區(qū)信息)
,rotected Function ReadString() As String

,,,im Offset As UInt32 = 0
,,,im TempByteArray(256) As Byte
,,,empByteArray(Offset) = FileStrm.ReadByte()
,,,hile (TempByteArray(Offset) <> &H0)
,,,,,ffset += 1
,,,,,empByteArray(Offset) = FileStrm.ReadByte()
,,,nd While

,,,eturn System.Text.Encoding.Default.GetString(TempByteArray)

,nd Function

,'從當(dāng)前文件位置讀取地區(qū)信息
Protected Function ReadArea() As String

,,,im Tag As Byte = GetTag()

,,,f (Tag = &H1 Or Tag = &H2) Then
,,,,,ileStrm.Seek(GetOffset(), SeekOrigin.Begin)
,,,,,eturn ReadString()
,,,lse
,,,,,ileStrm.Seek(-1, SeekOrigin.Current)
,,,,,eturn ReadString()
,,,nd If

,nd Function

,'從當(dāng)前文件位置讀取一個(gè)字節(jié)的標(biāo)識(shí)
,rotected Function GetTag() As Byte
,,eturn FileStrm.ReadByte()
End Function

,'得到指定索引位置的信息(IP起始范圍)
,rotected Function IndexInfoAtPos(ByVal Index_Pos As Int32) As CZ_INDEX_INFO

,,,im Index_Info As New CZ_INDEX_INFO
,,'根據(jù)索引編號(hào)計(jì)算出在文件中在偏移位置
,,,ileStrm.Seek(Index_Set + 7 * Index_Pos, SeekOrigin.Begin)
,,,ndex_Info.IpSet = GetUInt32()
,,,ndex_Info.Offset = GetOffset()
,,,ileStrm.Seek(Index_Info.Offset, SeekOrigin.Begin)
,,,ndex_Info.IpEnd = GetUInt32()

,,,eturn Index_Info

,nd Function

'讀取3個(gè)字節(jié),得到偏移位置
,rotected Function GetOffset() As UInt32

,,,im TempByte4(4) As Byte
,,,empByte4(0) = FileStrm.ReadByte()
,,empByte4(1) = FileStrm.ReadByte()
,,,empByte4(2) = FileStrm.ReadByte()
,,empByte4(3) = 0
,,eturn BitConverter.ToUInt32(TempByte4, 0)

,nd Function

,rotected Function GetUInt32() As UInt32

,,,im TempByte4(4) As Byte
,,,ileStrm.Read(TempByte4, 0, 4)
,,eturn BitConverter.ToUInt32(TempByte4, 0)

,nd Function


'將字符串的IP轉(zhuǎn)換成Int32
,ublic Shared Function IPToUInt32(ByVal Ipvalue As String) As UInt32

,,im IpByte() As String = Ipvalue.Split(".")
,,,im nUpperBound As Int32 = IpByte.GetUpperBound(0)
,,f nUpperBound <> 3 Then
,,,,,eDim Preserve IpByte(4)
,,,,,or i As Int32 = 1 To 3 - nUpperBound
,,,,,,,pByte(nUpperBound + i) = "0"
,,,,,ext
,,,nd If

,,,im TempByte4(4) As Byte
,,,or i As Int32 = 0 To 3
,,,,'如果是.Net 2.0可以支持TryParse。
,,,,,'If Not (Byte.TryParse(IpByte(i), TempByte4(3 - i))) Then
,,,',empByte4(3 - i) = &H0
,,,,'End If
,,,,f (IsNumeric(IpByte(i))) Then
,,,,,,,empByte4(3 - i) = CInt(IpByte(i)) And &HFF
,,,,,nd If
,,,ext

,,,eturn BitConverter.ToUInt32(TempByte4, 0)
,,,'System.Net.IPAddress.NetworkToHostOrder

,nd Function

,'將Int32型的IP轉(zhuǎn)換成字符串
Public Shared Function UInt32ToIP(ByVal UInt32value As UInt32) As String
,,,eturn New System.Net.IPAddress(System.Net.IPAddress.HostToNetworkOrder(UInt32value)).ToString()
,nd Function

End Class
關(guān)鍵詞:VS.NET