生成长度仅为25个字符的唯一ID(GUID)

时间:2013-09-20 20:21:18

标签: vb.net

生成长度为25个字符的unquie ID(无特殊字符)的最佳appraoch是什么?我正在考虑生成GUID并采用其子串,但我不知道这是否是唯一性的最佳选择。

这适用于已连接的系统。在我的情况下,在数据库中创建主键将不起作用。我需要手动创建一个unquie ID

我尝试了这个但是由于某些原因我在输出中看到重复。因此,即使在这个简单的测试中,它似乎也不太令人不安。

 Sub Main()
        Dim sb As StringBuilder = New StringBuilder
        For i As Integer = 1 To 100000
            Dim s As String = GenerateRandomString(25, True)
            sb.AppendLine(s)
            sb.AppendLine(Environment.NewLine)
        Next
        Console.WriteLine(sb.ToString)
        Console.ReadLine()
    End Sub

    Public Function GenerateRandomString(ByRef len As Integer, ByRef upper As Boolean) As String

        Dim rand As New Random()

        Dim allowableChars() As Char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789".ToCharArray()

        Dim final As String = String.Empty

        For i As Integer = 0 To len - 1

            final += allowableChars(rand.Next(allowableChars.Length - 1))
        Next

        Return IIf(upper, final.ToUpper(), final)

    End Function

3 个答案:

答案 0 :(得分:3)

您可能会看到重复项,因为New Random()是根据系统时钟播种的,这可能在下一次迭代时没有改变。

尝试加密安全的RNG:

Const ALLOWABLE_ALL As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Const ALLOWABLE_UPPERCASE As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim allowable As String = If(upper, ALLOWABLE_UPPERCASE, ALLOWABLE_ALL)
Dim result(len - 1) As Char
Dim current As Integer = 0

Using r As New Security.Cryptography.RNGCryptoServiceProvider()
    Do
        Dim buffer(255) As Byte
        r.GetBytes(buffer)

        For b As Byte In buffer
            If b < allowable.Length Then
                result(current) = allowable(b)
                current += 1
                If current = len Then Return New String(result)
            End If
        Next
    Loop
End Using

这也比您的实施“更随机”,因为如果upperTrue,那么字母的加权不会是两倍。

答案 1 :(得分:1)

GUID可能是32位数字,但仅限于以十六进制表示。这意味着它只会使用0-9和A-F字符。如果你的字符串可以使用整个字母表,那么你可以用更少的字符表达相同的GUID,特别是如果你的字符串可以区分大小写。

有关替代编码的示例,请参阅http://en.wikipedia.org/wiki/Globally_unique_identifier#Text_encoding;有关示例代码,请参阅http://web.archive.org/web/20100408172352/http://prettycode.org/2009/11/12/short-guid/。编辑:或者上面的汉斯方法要好得多。如果要编码仅包含A-Z,a-z和0-9字符的GUID,则需要查找Base-62编码(而不是base-64),因为您只需编码62个字符。

答案 2 :(得分:0)

停止尝试重新发明轮子并使用.NET的内置GUID生成器:

System.Guid.NewGuid()

将生成一个正确随机播种的GUID,然后简单地将其子串到您的限制。如果你抓住最后25个字符,而不是前25个字符,那就更好了。

PS:我一般认为这不是一个好主意,因为它是整个GUID,被认为是唯一的,不是它的一部分,但它应该满足你想要的。