C# 类似 YouTube 的 GUID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1458468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
YouTube-like GUID
提问by kusanagi
Is it possible to generate short GUID like in YouTube (N7Et6c9nL9w)?
是否可以像在 YouTube (N7Et6c9nL9w) 中一样生成短 GUID?
How can it be done? I want to use it in web app.
怎么做到呢?我想在网络应用程序中使用它。
采纳答案by bobbymcr
You could use Base64:
您可以使用 Base64:
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
That generates a string like E1HKfn68Pkms5zsZsvKONw==
. Since a GUID is always 128 bits, you can omit the ==
that you know will always be present at the end and that will give you a 22 character string. This isn't as short as YouTube though.
这会生成一个像E1HKfn68Pkms5zsZsvKONw==
. 由于 GUID 始终为 128 位,因此您可以省略==
您知道将始终出现在末尾的,这将为您提供 22 个字符的字符串。不过,这并不像 YouTube 那样短。
回答by Scott Muc
Technically it's not a Guid. Youtube has a simple randomized string generator that you can probably whip up in a few minutes using an array of allowed characters and a random number generator.
从技术上讲,它不是指南。Youtube 有一个简单的随机字符串生成器,您可能会在几分钟内使用一组允许的字符和一个随机数生成器快速创建。
回答by Robert Christie
This id is probably not globally unique. GUID's should be globally unique as they include elements which should not occur elsewhere (the MAC address of the machine generating the ID, the time the ID was generated, etc.)
这个 id 可能不是全局唯一的。GUID 应该是全局唯一的,因为它们包含不应出现在其他地方的元素(生成 ID 的机器的 MAC 地址、生成 ID 的时间等)
If what you need is an ID that is unique within your application, use a number fountain - perhaps encoding the value as a hexadecimal number. Every time you need an id, grab it from the number fountain.
如果您需要的是应用程序中唯一的 ID,请使用数字喷泉 - 可能将值编码为十六进制数字。每次你需要一个 id 时,从数字喷泉中获取它。
If you have multiple servers allocating id's, you could grab a range of numbers (a few tens or thousands depending on how quickly you're allocating ids) and that should do the job. an 8 digit hex number will give you 4 billion ids - but your first id's will be a lot shorter.
如果您有多个服务器分配 id,您可以获取一系列数字(几十或几千取决于您分配 id 的速度),这应该可以完成工作。一个 8 位的十六进制数字会给你 40 亿个 ID——但你的第一个 ID 会短得多。
回答by eglasius
9 chars is not a Guid. Given that, you could use the hexadecimal representation of an int, which gives you a 8 char string.
9 个字符不是 Guid。鉴于此,您可以使用 int 的十六进制表示,它为您提供 8 个字符的字符串。
Update 1:Dunno why the above got a downvote, but for anyone wondering:
更新 1:不知道为什么上述内容遭到否决,但对于任何想知道的人:
You can use an id you might already have. Also you can use .GetHashCode against different simple types and there you have a different int. You can also xor different fields. And if you are into it, you might even use a Random number - hey, you have well above 2.000.000.000+ possible values if you stick to the positives ;)
您可以使用您可能已经拥有的 ID。你也可以对不同的简单类型使用 .GetHashCode 并且你有一个不同的 int。您还可以异或不同的字段。如果你喜欢它,你甚至可以使用一个随机数 - 嘿,如果你坚持积极的一面,你的可能值远远高于 2.000.000.000+ ;)
回答by philipproplesch
It might be not the best solution, but you can do something like that:
这可能不是最好的解决方案,但您可以执行以下操作:
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
回答by Chad Levy
As others have mentioned, YouTube's VideoId
is not technically a GUID since it's not inherently unique.
正如其他人所提到的,YouTube 在VideoId
技术上并不是一个 GUID,因为它本质上并不是唯一的。
As per Wikipedia:
根据维基百科:
The total number of unique keys is 2128or 3.4×1038. This number is so large that the probability of the same number being generated randomly twice is negligible.
唯一键的总数为 2 128或 3.4×10 38。这个数字太大了,同一个数字随机生成两次的概率可以忽略不计。
The uniqueness YouTube's VideoId
is maintained by their generator algorithm.
YouTube 的唯一性VideoId
由其生成器算法维护。
You can either write your own algorithm, or you can use some sort of random string generator and utilize the UNIQUE CONSTRAINT
constraint in SQL to enforce its uniqueness.
您可以编写自己的算法,也可以使用某种随机字符串生成器并利用UNIQUE CONSTRAINT
SQL 中的约束来强制其唯一性。
First, create a UNIQUE CONSTRAINT
in your database:
首先,UNIQUE CONSTRAINT
在您的数据库中创建一个:
ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);
Then, for example, generate a random string (from philipproplesch's answer):
然后,例如,生成一个随机字符串(来自 philipproplesch's answer):
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
If the generated UrlId
is sufficiently random and sufficiently long you should rarely encounter the exception that is thrown when SQL encounters a duplicate UrlId
. In such an event, you can easily handle the exception in your web app.
如果生成UrlId
的足够随机且足够长,您应该很少会遇到 SQL 遇到重复项时抛出的异常UrlId
。在这种情况下,您可以轻松处理 Web 应用程序中的异常。
回答by Gilthans
As mentioned in the accepted answer, it can cause problems if you're using the GUID in the URL. Here is a more complete answer:
如已接受的答案中所述,如果您在 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);
}
Usage:
用法:
var guid = Guid.NewGuid();
var shortStr = ToShortString(guid);
// shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
var guid2 = FromShortString(shortStr);
Assert.AreEqual(guid, guid2);
回答by Vinod Srivastav
It's not a GUID
这不是一个 GUID
Let me jump in with the following
让我跳入以下内容
It uses the TotalMilliseconds
from EPOCH
and a valid set of characters.
它使用TotalMilliseconds
fromEPOCH
和一组有效的字符。
This will not be globally unique but unique to the instance where it's defines
这将不是全局唯一的,而是对其定义的实例唯一的
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);
}
The output will come something like
输出将类似于
XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE
Update:The same can be achieved from Guid
as
更新:同样可以实现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);
For a Guid ecd65132-ab5a-4587-87b8-b875e2fe0f35
it will break it down in chunks as ecd65132
,ab5a
, 4587
,87b8
,b875e2fe0f35
对于 Guid,ecd65132-ab5a-4587-87b8-b875e2fe0f35
它会将其分解为ecd65132
, ab5a
, 4587
, 87b8
,b875e2fe0f35
but i can't guarantee it to be unique always.
但我不能保证它总是独一无二的。
Update 2:There is also a project called ShortGuidto get a url friendly GUID
it can be converted fron/to a regular Guid
更新 2:还有一个名为ShortGuid的项目来获得一个友好的 urlGUID
可以将它转换为常规Guid