【VB.NET】經過 IPIP.NET 數據庫來查詢IP地址

上一次介紹了利用純真數據庫查詢IP地址詳細信息的方法。
然而純真數據庫是由網友反饋所提供的,不少數據描述並不許確,因此我上網找了一些其餘的IP數據庫,最後就找到了 ipip.net 這個網站所提供的IP數據庫。html

IPIP所提供的數據庫有付費和免費兩個版本,咱們能夠直接使用其中的免費版本。
下載地址 https://www.ipip.net/download.html (須要先註冊一個賬號)
壓縮包內有一個PHP的解析類,還有一個 17monipdb.dat 文件就是數據庫了,咱們只須要用到它就能夠了。數據庫

將 17monipdb.dat 複製到程序的主目錄,使用下面的代碼:測試

Imports System.IO
Imports System.Text

Public Class IPIP

    Shared offset As Integer
    Shared index As UInteger() = New UInteger(255) {}
    Shared dataBuffer As Byte()
    Shared indexBuffer As Byte()
    Shared lastModifyTime As Long = 0L
    Shared ipFile As String

    Shared rwlock As New Threading.ReaderWriterLock


    Shared Sub New()
        Load("17monipdb.dat")
    End Sub

    Shared Sub Load(ByVal filename As String)
        ipFile = New FileInfo(filename).FullName
        Load()
    End Sub

    Shared Sub Load()
        rwlock.AcquireWriterLock(-1)

        Dim fi As New FileInfo(ipFile)
        lastModifyTime = fi.LastWriteTime.Ticks

        Try
            dataBuffer = File.ReadAllBytes(fi.FullName)

            Dim indexLength = BytesToLong(dataBuffer(0), dataBuffer(1), dataBuffer(2), dataBuffer(3))
            indexBuffer = New Byte(indexLength - 1) {}
            Array.Copy(dataBuffer, 4, indexBuffer, 0, indexLength)
            offset = CType(indexLength, Integer)
            
            For lp As Integer = 0 To 255

                index(lp) = BytesToLong( _
                 indexBuffer(lp * 4 + 3), _
                 indexBuffer(lp * 4 + 2), _
                 indexBuffer(lp * 4 + 1), _
                 indexBuffer(lp * 4) _
                 )

            Next

        Catch ex As Exception
            Throw ex
        End Try

        rwlock.ReleaseWriterLock()
    End Sub




    Private Shared Function BytesToLong(ByVal a As Byte, ByVal b As Byte, ByVal c As Byte, ByVal d As Byte) As UInteger
        Return (CType(a, UInteger) << 24) Or (CType(b, UInteger) << 16) Or (CType(c, UInteger) << 8) Or d
    End Function


    Shared Function Find(ByVal ip As String) As String()
        rwlock.AcquireReaderLock(-1)

        Dim ips = ip.Split(".")
        Dim ip_prefix_value = Integer.Parse(ips(0))
        Dim ip2long_value As Long = BytesToLong(Byte.Parse(ips(0)), Byte.Parse(ips(1)), Byte.Parse(ips(2)), Byte.Parse(ips(3)))
        Dim start = index(ip_prefix_value)
        Dim max_comp_len = offset - 1028

        Dim index_offset As Long = -1L
        Dim index_length As Integer = -1
        Dim b As Byte = 0

        start = start * 8 + 1024
        While start < max_comp_len
            If BytesToLong(indexBuffer(start + 0), indexBuffer(start + 1), indexBuffer(start + 2), indexBuffer(start + 3)) >= ip2long_value Then
                index_offset = BytesToLong(b, indexBuffer(start + 6), indexBuffer(start + 5), indexBuffer(start + 4))
                index_length = &HFF And indexBuffer(start + 7)
                Exit While
            End If
            start += 8
        End While

        Dim areaBytes = New Byte(index_length - 1) {}
        Array.Copy(dataBuffer, offset + index_offset - 1024, areaBytes, 0, index_length)

        Dim ret As String() = Encoding.UTF8.GetString(areaBytes).Split(vbTab)

        rwlock.ReleaseReaderLock()

        Return ret
    End Function
    
End Class

此代碼是我從官方提供的C#版本翻譯過來的,而且去除了一些冗餘代碼,只留下核心功能。
未通過徹底的測試,有BUG請反饋給我。網站

 

使用方法很簡單:ui

Dim ret = IPIP.Find("127.0.0.1")
' 用換行分隔全部信息
Dim ipdesc = String.Join(vbCrLf, ret)
相關文章
相關標籤/搜索