66

是否可以像在 YouTube (N7Et6c9nL9w) 中那样生成短 GUID?

怎么做到呢?我想在网络应用程序中使用它。

4

8 回答 8

72

您可以使用 Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

这会生成一个像E1HKfn68Pkms5zsZsvKONw==. 由于 GUID 始终为 128 位,因此您可以省略==您知道将始终出现在末尾的那个,这将给您一个 22 个字符的字符串。不过,这并不像 YouTube 那样短。

于 2009-09-22T06:51:57.363 回答
24

如已接受的答案中所述,如果您在 URL 中使用 GUID,可能会导致问题。这是一个更完整的答案:

    public string ToShortString(Guid guid)
    {
        var base64Guid = Convert.ToBase64String(guid.ToByteArray());

        // Replace URL unfriendly characters with better ones
        base64Guid = base64Guid.Replace('+', '-').Replace('/', '_');

        // Remove the trailing ==
        return base64Guid.Substring(0, base64Guid.Length - 2);
    }

    public Guid FromShortString(string str)
    {
        str = str.Replace('_', '/').Replace('-', '+');
        var byteArray = Convert.FromBase64String(str + "==");
        return new Guid(byteArray);
    }

用法:

        var guid = Guid.NewGuid();
        var shortStr = ToShortString(guid);
        // shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
        var guid2 = FromShortString(shortStr);
        Assert.AreEqual(guid, guid2);
于 2016-12-01T17:39:57.137 回答
11

9 个字符不是 GUID。鉴于此,您可以使用 int 的十六进制表示,它为您提供 8 个字符的字符串。

您可以使用您可能已经拥有的 id。您也可以.GetHashCode针对不同的简单类型使用,并且您有不同的 int。您还可以异或不同的字段。如果你喜欢它,你甚至可以使用随机数 - 嘿,如果你坚持积极的态度,你的可能值远高于 2.000.000.000 ;)

于 2009-09-22T07:03:43.160 回答
9

这不是 GUID

让我跳入以下内容

它使用TotalMillisecondsfromEPOCH和一组有效的字符。

这不会是全局唯一的,但对于它定义的实例来说是唯一的

public string YoutubeLikeId()
{
    Thread.Sleep(1);//make everything unique while looping
    long ticks = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1,0,0,0,0))).TotalMilliseconds;//EPOCH
    char[] baseChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
    
    int i = 32;
    char[] buffer = new char[i];
    int targetBase= baseChars.Length;

    do
    {
        buffer[--i] = baseChars[ticks % targetBase];
        ticks = ticks / targetBase;
    }
    while (ticks > 0);

    char[] result = new char[32 - i];
    Array.Copy(buffer, i, result, 0, 32 - i);

    return new string(result);
}

输出将类似于

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE

更新:同样可以从Guidas

var guid = Guid.NewGuid(); 
guid.ToString("N");
guid.ToString("N").Substring(0,8);
guid.ToString("N").Substring(8,4);
guid.ToString("N").Substring(12,4);
guid.ToString("N").Substring(16,4);
guid.ToString("N").Substring(20,12);

对于 Guid ecd65132-ab5a-4587-87b8-b875e2fe0f35,它会将其分解为ecd65132, ab5a, 4587, 87b8,b875e2fe0f35

但我不能保证它总是独一无二的。

更新 2:还有一个名为ShortGuid的项目以获得友好的 url GUID,它可以从/转换为常规Guid

它通过将GuidBase64 编码为以下代码来工作

public static string Encode(Guid guid)
{
    string encoded = Convert.ToBase64String(guid.ToByteArray());

    encoded = encoded
        .Replace("/", "_")
        .Replace("+", "-");
    return encoded.Substring(0, 22);
}

关于它的好处是可以再次解码以Guid获取

public static Guid Decode(string value)
{
    // avoid parsing larger strings/blobs
    if (value.Length != 22)
    {
        throw new ArgumentException("A ShortGuid must be exactly 22 characters long. Receive a character string.");
    }

    string base64 = value
        .Replace("_", "/")
        .Replace("-", "+") + "==";

    byte[] blob = Convert.FromBase64String(base64);
    var guid = new Guid(blob);

    var sanityCheck = Encode(guid);
    if (sanityCheck != value)
    {
        throw new FormatException(
            @"Invalid strict ShortGuid encoded string. The string '{value}' is valid URL-safe Base64, " +
            @"but failed a round-trip test expecting '{sanityCheck}'."
        );
    }

    return guid;
}

所以一个 Guid4039124b-6153-4721-84dc-f56f5b057ac2将被编码为SxI5QFNhIUeE3PVvWwV6wg并且输出看起来像。

ANf-MxRHHky2TptaXBxcwA
zpjp-stmVE6ZCbOjbeyzew
jk7P-XYFokmqgGguk_530A
81t6YZtkikGfLglibYkDhQ
qiM2GmqCK0e8wQvOSn-zLA
于 2019-05-24T11:00:08.070 回答
7

正如其他人所提到的,YouTube 在VideoId技术上并不是 GUID,因为它本身并不是唯一的。

根据维基百科

唯一键的总数为 2 128或 3.4×10 38。这个数字是如此之大,以至于同一数字随机生成两次的概率可以忽略不计。

YouTube 的独特性VideoId由他们的生成器算法维护。

您可以编写自己的算法,也可以使用某种随机字符串生成器并利用UNIQUE CONSTRAINTSQL 中的约束来强制其唯一性。

UNIQUE CONSTRAINT首先,在您的数据库中创建一个:

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

然后,例如,生成一个随机字符串(来自 philipproplesch 的回答):

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);

如果生成UrlId的足够随机且足够长,您应该很少遇到 SQL 遇到重复时引发的异常UrlId。在这种情况下,您可以轻松地处理 Web 应用程序中的异常。

于 2011-10-19T17:49:21.287 回答
4

从技术上讲,它不是指南。Youtube 有一个简单的随机字符串生成器,您可以使用一组允许的字符和一个随机数生成器在几分钟内完成它。

于 2009-09-22T06:50:22.437 回答
3

这可能不是最好的解决方案,但你可以这样做:

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
于 2009-09-22T08:10:33.040 回答
2

这个 id 可能不是全局唯一的。GUID 应该是全局唯一的,因为它们包含不应在其他地方出现的元素(生成 ID 的机器的 MAC 地址、生成 ID 的时间等)

如果您需要的是在您的应用程序中唯一的 ID,请使用数字喷泉 - 可能将该值编码为十六进制数字。每次你需要一个 id 时,从数字喷泉中获取它。

如果您有多个服务器分配 id,您可以获取一系列数字(几十或几千取决于您分配 id 的速度),这应该可以完成工作。一个 8 位十六进制数字将为您提供 40 亿个 id - 但您的第一个 id 会短得多。

于 2009-09-22T06:55:32.440 回答