Vb.net 生成长度仅为25个字符的取消静止Id(GUID)

Vb.net 生成长度仅为25个字符的取消静止Id(GUID),vb.net,Vb.net,生成长度为25个字符的非静态ID(无特殊字符)的最佳方法是什么?我正在考虑生成一个GUID并获取它的子字符串,但我不知道这是否是唯一性的最佳方案 这是供断开连接的系统使用的。在数据库中创建主键在我的情况下不起作用。我需要手动创建一个取消静止ID 我尝试过这个,但由于某种原因,我在输出中看到了重复项。因此,即使在这个简单的测试中也不会显得太不平静 Sub Main() Dim sb As StringBuilder = New StringBuilder For

生成长度为25个字符的非静态ID(无特殊字符)的最佳方法是什么?我正在考虑生成一个GUID并获取它的子字符串,但我不知道这是否是唯一性的最佳方案

这是供断开连接的系统使用的。在数据库中创建主键在我的情况下不起作用。我需要手动创建一个取消静止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

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


有关替代编码的示例或示例代码,请参见。编辑:或者汉斯的方法,上面哪个更好。如果您希望仅使用a-Z、a-Z和0-9个字符对GUID进行编码,则需要查找Base-62编码(与Base-64相反),因为您只有62个字符可编码。

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


有关替代编码的示例或示例代码,请参见。编辑:或者汉斯的方法,上面哪个更好。如果您想只使用a-Z、a-Z和0-9个字符对GUID进行编码,则需要查找Base-62编码(与Base-64相反),因为您只有62个字符可编码。

停止尝试重新发明控制盘,只需使用.NET内置的GUID生成器即可:

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


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

< P>不要试图重新发明轮子,只使用.NET的内置GUID生成器:

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


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

< P>你可能会看到重复,因为<代码>新的随机化(<)>代码是根据系统时钟来播种的,这在下一次迭代中可能没有改变。 尝试加密安全的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
Const allowed_ALL As String=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789”
常量允许大小写为String=“abcdefghijklmnopqrstuvxyz012456789”
允许标注为字符串=If(大写,允许大写,允许全部)
Dim结果(len-1)作为字符
将当前变暗为整数=0
将r用作新的Security.Cryptography.RNGCryptoServiceProvider()
做
Dim缓冲区(255)作为字节
r、 GetBytes(缓冲区)
对于b,作为缓冲区中的字节
如果b<允许长度,则
结果(电流)=允许值(b)
电流+=1
如果current=len,则返回新字符串(结果)
如果结束
下一个
环
终端使用

这也比您的实现“更随机”,因为如果
upper
True

,则字母的权重不会增加两倍,因为
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
Const allowed_ALL As String=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789”
常量允许大小写为String=“abcdefghijklmnopqrstuvxyz012456789”
允许标注为字符串=If(大写,允许大写,允许全部)
Dim结果(len-1)作为字符
将当前变暗为整数=0
将r用作新的Security.Cryptography.RNGCryptoServiceProvider()
做
Dim缓冲区(255)作为字节
r、 GetBytes(缓冲区)
对于b,作为缓冲区中的字节
如果b<允许长度,则
结果(电流)=允许值(b)
电流+=1
如果current=len,则返回新字符串(结果)
如果结束
下一个
环
终端使用

这也比您的实现“更随机”,因为如果
upper
True

不,这不是一个好主意。获取唯一ID非常简单,比上一个ID多1个。以一种可靠的方式存储前一个是您需要解决的问题。任何数据库都知道如何做到这一点。我们是说在单独的断开连接的物理位置生成此ID吗?是的,Pat,我不能简单地从数据库生成ID,它们需要手动生成。您可以提供更多上下文吗?您可以为您的应用程序提供一个单例服务,该服务允许用户请求一些您将存储在应用程序端的预分配ID。服务不一定是数据库。不,这不是个好主意。获取唯一ID非常简单,比上一个ID多1个。以一种可靠的方式存储前一个是您需要解决的问题。任何数据库都知道如何做到这一点。我们是说在单独的断开连接的物理位置生成此ID吗?是的,Pat,我不能简单地从数据库生成ID,它们需要手动生成。您可以提供更多上下文吗?您可以为您的应用程序提供一个单例服务,该服务允许用户请求一些您将存储在应用程序端的预分配ID。这项服务不一定要b