微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过IPIP.NET实现数据库来查询IP地址的实例

上一次介绍了利用纯真数据库查询IP地址详细信息的方法
然而纯真数据库是由网友反馈所提供的,很多数据描述并不准确,所以我上网找了一些其他的IP数据库,最后就找到了 ipip.net 这个网站所提供的IP数据库

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请反馈给我。

使用方法很简单:

Dim ret = IPIP.Find(127.0.0.1
' 用换行分隔所有信息
Dim ipdesc = String.Join(vbCrLf, ret)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐