VB.net中不可复制的随机数



我想在不重复相同IP地址的情况下生成200000个随机IP地址例如:

(1-254)。(1-254)。(1-254).1-254)

在vb.net中我的代码是:

        While c < 200001
        IP = random.Next(1, 254).ToString + "." + random.Next(1, 254).ToString + "." +           random.Next(1, 254).ToString + "." + random.Next(1, 254).ToString
        On Error Resume Next
        IPHost = Dns.GetHostEntry(IP.ToString)
        domain = IPHost.HostName.ToString()
        objWriter.Write(IP)
        objWriter.Write("   ")
        objWriter.WriteLine(domain)
        TextBox1.Text = IP
        Application.DoEvents()
    End While
    objWriter.Close()
    MsgBox("DONE")

关于

绕过保留IP块等问题,只需将生成的IP写入Collection,然后调用集合的Contains()方法来检查集合中是否存在生成的IP。

正如@Heinzi所指出的,HashSet也是一种选择——也许是更好的选择,因为你要向它写入200000个条目。

由于IP4地址由4个字节组成,您可以简单地使用Random.NextBytes和大小为4的数组来创建一个地址。

为了防止创建重复地址,只需使用HashSetwhile循环。

要过滤掉保留地址,您只需使用此答案中使用的代码(一些保留地址很容易检查,例如,多播地址都以1110开头,但无需在此处重新发明轮子)。我把它转换成下面的VB.Net

所以你的代码可能是这样的:

Dim r = New Random()
Dim addresses = New HashSet(Of String)()
While addresses.Count < 200000
    Dim buffer As Byte() = New Byte(3) {}
    r.NextBytes(buffer)
    Dim address = String.Join(".", buffer)
    If Not IsNonRoutableIpAddress(address) Then
        addresses.Add(address)
    End If
End While

以及IsNonRouteableIpAddress:的转换代码

Public Shared Function IsNonRoutableIpAddress(ipAddress__1 As String) As Boolean
    'Reference: http://en.wikipedia.org/wiki/Reserved_IP_addresses
    'if the ip address string is empty or null string, we consider it to be non-routable
    If [String].IsNullOrEmpty(ipAddress__1) Then
        Return True
    End If
    'if we cannot parse the Ipaddress, then we consider it non-routable
    Dim tempIpAddress As IPAddress = Nothing
    If Not IPAddress.TryParse(ipAddress__1, tempIpAddress) Then
        Return True
    End If
    Dim ipAddressBytes As Byte() = tempIpAddress.GetAddressBytes()
    'if ipAddress is IPv4
    If tempIpAddress.AddressFamily = System.Net.Sockets.AddressFamily.InterNetwork Then
        If IsIpAddressInRange(ipAddressBytes, "10.0.0.0/8") Then
            'Class A Private network check
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "172.16.0.0/12") Then
            'Class B private network check
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "192.168.0.0/16") Then
            'Class C private network check
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "127.0.0.0/8") Then
            'Loopback
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "0.0.0.0/8") Then
            'reserved for broadcast messages
            Return True
        End If
        'its routable if its ipv4 and meets none of the criteria
        Return False
    'if ipAddress is IPv6
    ElseIf tempIpAddress.AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
        'incomplete
        If IsIpAddressInRange(ipAddressBytes, "::/128") Then
            'Unspecified address
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "::1/128") Then
            'lookback address for localhost
            Return True
        ElseIf IsIpAddressInRange(ipAddressBytes, "2001:db8::/32") Then
            'Addresses used in documentation
            Return True
        End If
        Return False
    Else
        'we default to non-routable if its not Ipv4 or Ipv6
        Return True
    End If
End Function
''' <summary>
''' 
''' </summary>
''' <param name="ipAddressBytes"></param>
''' <param name="reservedIpAddress"></param>
''' <returns></returns>
Private Shared Function IsIpAddressInRange(ipAddressBytes As Byte(), reservedIpAddress As String) As Boolean
    If [String].IsNullOrEmpty(reservedIpAddress) Then
        Return False
    End If
    If ipAddressBytes Is Nothing Then
        Return False
    End If
    'Split the reserved ip address into a bitmask and ip address
    Dim ipAddressSplit As String() = reservedIpAddress.Split(New Char() {"/"C}, StringSplitOptions.RemoveEmptyEntries)
    If ipAddressSplit.Length <> 2 Then
        Return False
    End If
    Dim ipAddressRange As String = ipAddressSplit(0)
    Dim ipAddress__1 As IPAddress = Nothing
    If Not IPAddress.TryParse(ipAddressRange, ipAddress__1) Then
        Return False
    End If
    ' Convert the IP address to bytes.
    Dim ipBytes As Byte() = ipAddress__1.GetAddressBytes()
    'parse the bits
    Dim bits As Integer = 0
    If Not Integer.TryParse(ipAddressSplit(1), bits) Then
        bits = 0
    End If
    ' BitConverter gives bytes in opposite order to GetAddressBytes().
    Dim maskBytes As Byte() = Nothing
    If ipAddress__1.AddressFamily = AddressFamily.InterNetwork Then
        Dim mask As UInteger = Not (UInteger.MaxValue >> bits)
        maskBytes = BitConverter.GetBytes(mask).Reverse().ToArray()
    ElseIf ipAddress__1.AddressFamily = AddressFamily.InterNetworkV6 Then
        '128 places
        Dim bitArray As New BitArray(128, False)
        'shift <bits> times to the right
        ShiftRight(bitArray, bits, True)
        'turn into byte array
        maskBytes = ConvertToByteArray(bitArray).Reverse().ToArray()
    End If

    Dim result As Boolean = True
    'Calculate
    For i As Integer = 0 To ipBytes.Length - 1
        result = result And CByte(ipAddressBytes(i) And maskBytes(i)) = ipBytes(i)
    Next
    Return result
End Function
''' <summary>
''' 
''' </summary>
''' <param name="bitArray"></param>
''' <param name="shiftN"></param>
''' <param name="fillValue"></param>
Private Shared Sub ShiftRight(bitArray As BitArray, shiftN As Integer, fillValue As Boolean)
    For i As Integer = shiftN To bitArray.Count - 1
        bitArray(i - shiftN) = bitArray(i)
    Next
    'fill the shifted bits as false
    For index As Integer = bitArray.Count - shiftN To bitArray.Count - 1
        bitArray(index) = fillValue
    Next
End Sub
''' <summary>
''' 
''' </summary>
''' <param name="bitArray"></param>
''' <returns></returns>
Private Shared Function ConvertToByteArray(bitArray As BitArray) As Byte()
    ' pack (in this case, using the first bool as the lsb - if you want
    ' the first bool as the msb, reverse things ;-p)
    Dim bytes As Integer = (bitArray.Length + 7) / 8
    Dim arr2 As Byte() = New Byte(bytes - 1) {}
    Dim bitIndex As Integer = 0
    Dim byteIndex As Integer = 0
    For i As Integer = 0 To bitArray.Length - 1
        If bitArray(i) Then
            arr2(byteIndex) = arr2(byteIndex) Or CByte(1 << bitIndex)
        End If
        bitIndex += 1
        If bitIndex = 8 Then
            bitIndex = 0
            byteIndex += 1
        End If
    Next
    Return arr2
End Function

最新更新