有没有方法可以创建类似于短GUID的短唯一代码?

28

我想创建一个短的 GUID。有没有类似短GUID这样的方法来创建短的唯一代码? 我想创建一个票据跟踪号码。


3
越短越不唯一(注意,Guid并非真正“唯一”)。有多短?可能来自数据库的标识键吗? - Marc Gravell
1
@Lasse Guid的某些部分不能保证是唯一的。 - Michael Stum
2
@Marc:你连续中1000次彩票的机会都比生成两个相同的GUID更大! ;) - Mitch Wheat
2
@Mitch 没错!有机会的!我想表达的是,大小与独特性有关,而且从技术上讲,即使有很大的数字,你也不能绝对保证唯一性。因此,理解问题的背景非常重要,这就是为什么在这里需要更多信息的提示。 - Marc Gravell
如果您不需要超过63位密钥,您可以使用长整型 https://github.com/joshclark/Flakey 来获得相同的结果(如果您想要更好的人类可读性,仍然可以对其进行编码)。 - Chris Marisic
显示剩余7条评论
6个回答

19

GUID的长度为128位(16字节),如果您要创建一个短GUID,则必须更改GUID的编码方式。

例如,您可以使用base64或ASCII85编码。

    /// <summary>
    /// Creates a GUID which is guaranteed not to equal the empty GUID
    /// </summary>
    /// <returns>A 24 character long string</returns>
    public static string CreateGuid()
    {
        Guid guid = Guid.Empty;
        while (Guid.Empty == guid)
        {
            guid = Guid.NewGuid();
        }

        // Uses base64 encoding the guid.(Or  ASCII85 encoded)
        // But not recommend using Hex, as it is less efficient.
        return Convert.ToBase64String(guid.ToByteArray());
    }

16

3
资源真的很好,但如果您能够包含足够的文章信息以便制作一个20个字符的指南,这将非常有帮助,以防该文章从互联网上移除。 - Richard Garside
似乎已经发生了这种情况。是时候重新发明轮子了... - Scott Means

5

在一年内唯一,外观“随机”

string UniqueID()
{
    var t = DateTime.UtcNow;
    long dgit = t.Millisecond   * 1000000000L +
                t.DayOfYear     * 1000000L +
                t.Hour          * 10000L +
                t.Minute        * 100L +
                t.Second;
    return Convert.ToBase64String(BitConverter.GetBytes(dgit).Take(5).ToArray()).TrimEnd('=');
}

这是一个可定制字符集的示例。

string UniqueID(string CharList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
    var t = DateTime.UtcNow;
    char[] charArray = CharList.ToCharArray();
    var result = new Stack<char>();

    var length = charArray.Length;

    long dgit = 1000000000000L +
                t.Millisecond   * 1000000000L +
                t.DayOfYear     * 1000000L +
                t.Hour          * 10000L +
                t.Minute        * 100L +
                t.Second;

    while (dgit != 0)
    {
        result.Push(charArray[dgit % length]);
        dgit /= length;
    }
    return new string(result.ToArray());
}

1
请注意,例如在循环中使用此方法时,它会一遍又一遍地生成相同的ID,直到经过一毫秒为止。 - Viezevingertjes

4
尝试使用Base 36,只需使用自动编号并将其保存为Base36即可获得唯一的数字。但是,为了使它们随机化,您需要其他东西。
我将对票号进行哈希或加密以作为票务跟踪代码。例如,
  code = Base36(MD5(ticketID+"my secrete"));

如果您希望跟踪代码是唯一的,那么我将使用一些密钥进行加密。

4

这取决于您的使用情况。

例如,如果您的生成速度小于每秒1个,可以递增一个32位整数(比128位GUID小四分之一)。这样的话,在每秒生成一个的速率下,它将持续超过68年。

如果您计算出您的使用情况,就可以很容易地确定最小的大小。此外,这也取决于您是否想在任何地方生成它们,还是它们将由单个服务器或软件生成。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接