是否可以像在YouTube(N7Et6c9nL9w)中生成简短的GUID一样?
怎么做?我想在网络应用中使用它。
答案 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
,它将以ecd65132
,ab5a
,4587
,87b8
,b875e2fe0f35
的形式将其分解为>
但是我不能保证它总是唯一的。