类似YouTube的GUID

kus*_*agi 47 .net c# url-shortener

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

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

bob*_*mcr 53

您可以使用Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
Run Code Online (Sandbox Code Playgroud)

这会生成一个字符串E1HKfn68Pkms5zsZsvKONw==.由于GUID始终是128位,因此您可以省略==您知道将始终存在的结尾,这将为您提供22个字符的字符串.这并不像YouTube那么短.

  • 这种方法的缺点是,生成的值可能包含斜杠(/)符号,如果处理不当,可能会对Url中的ussage不方便. (29认同)
  • 只需将'/'和'+'替换为URL安全字符,例如' - '和'_'.然后,当重新读取guid时,在解码之前将它们替换回来. (4认同)
  • 因此,通过用友好的URL替换有问题的字符('+'和'/')(例如' - '和'_'),仍然可以保证它是一个独特的Guid? (3认同)
  • 虽然我真的很喜欢这个解决方案,但我同意Jhonny D.不仅'/'可以出现,而且'+'也会完全打破你的网址.*叹* (2认同)

egl*_*ius 11

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

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

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


Cha*_*evy 7

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

根据维基百科

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

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

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

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

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);
Run Code Online (Sandbox Code Playgroud)

然后,例如,生成一个随机字符串(来自 philipproplesch's answer):

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
Run Code Online (Sandbox Code Playgroud)

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


Gil*_*ans 7

如在接受的答案中提到的,如果您在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);
    }
Run Code Online (Sandbox Code Playgroud)

用法:

        var guid = Guid.NewGuid();
        var shortStr = ToShortString(guid);
        // shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
        var guid2 = FromShortString(shortStr);
        Assert.AreEqual(guid, guid2);
Run Code Online (Sandbox Code Playgroud)


Vin*_*tav 7

这不是一个 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);
}
Run Code Online (Sandbox Code Playgroud)

输出将类似于

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE
Run Code Online (Sandbox Code Playgroud)

更新:同样可以实现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);
Run Code Online (Sandbox Code Playgroud)

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

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

更新 2:还有一个名为ShortGuid的项目来获得一个友好的 urlGUID可以将它转换为常规Guid

它的工作原理是Guid将 Base64编码为下面的代码

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);
}
Run Code Online (Sandbox Code Playgroud)

关于它的好处是可以再次解码以Guid返回

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE
Run Code Online (Sandbox Code Playgroud)

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

ANf-MxRHHky2TptaXBxcwA
zpjp-stmVE6ZCbOjbeyzew
jk7P-XYFokmqgGguk_530A
81t6YZtkikGfLglibYkDhQ
qiM2GmqCK0e8wQvOSn-zLA
Run Code Online (Sandbox Code Playgroud)