类似YouTube的GUID

时间:2009-09-22 06:45:04

标签: c# .net url-shortener

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

怎么做?我想在网络应用中使用它。

8 个答案:

答案 0 :(得分:48)

您可以使用Base64:

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

生成类似E1HKfn68Pkms5zsZsvKONw==的字符串。由于GUID始终为128位,因此您可以省略最后总是存在的==,这将为您提供22个字符的字符串。这并不像YouTube那么短。

答案 1 :(得分:11)

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

更新1: Dunno为什么上面有一个downvote,但对于任何想知道的人:

您可以使用您可能已拥有的ID。你也可以对不同的简单类型使用.GetHashCode,你有一个不同的int。您还可以xor不同的字段。如果你进入它,你甚至可以使用一个随机数 - 嘿,如果你坚持积极的话,你就有超过2.000.000.000+可能值;)

答案 2 :(得分:5)

如在接受的答案中提到的那样,如果您在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);

答案 3 :(得分:4)

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

根据Wikipedia

  

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

唯一性YouTube的VideoId由其生成器算法维护。

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

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

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

然后,例如,生成一个随机字符串(来自philipproplesch的{​​{3}}):

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

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

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

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

答案 6 :(得分:2)

此ID可能不是全局唯一的。 GUID应该是全局唯一的,因为它们包括不应发生在其他地方的元素(生成ID的机器的MAC地址,生成ID的时间等)。

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

如果您有多个服务器分配ID,您可以获取一系列数字(几十或几千,具体取决于您分配ID的速度),这应该可以胜任。一个8位十六进制数字将给你40亿个ID - 但你的第一个id会短得多。

答案 7 :(得分:0)

  

它不是GUID

让我从 EPOCH 中访问TotalMilliseconds,并输入一组有效的字符。

  

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

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 = new char[] { '0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'};

    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

更新:从Guid可以实现

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,它将以ecd65132ab5a458787b8b875e2fe0f35的形式将其分解为

  

但是我不能保证它总是唯一的。