是否可以像在 YouTube (N7Et6c9nL9w) 中那样生成短 GUID?
怎么做到呢?我想在网络应用程序中使用它。
您可以使用 Base64:
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
这会生成一个像E1HKfn68Pkms5zsZsvKONw==
. 由于 GUID 始终为 128 位,因此您可以省略==
您知道将始终出现在末尾的那个,这将给您一个 22 个字符的字符串。不过,这并不像 YouTube 那样短。
如已接受的答案中所述,如果您在 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);
9 个字符不是 GUID。鉴于此,您可以使用 int 的十六进制表示,它为您提供 8 个字符的字符串。
您可以使用您可能已经拥有的 id。您也可以.GetHashCode
针对不同的简单类型使用,并且您有不同的 int。您还可以异或不同的字段。如果你喜欢它,你甚至可以使用随机数 - 嘿,如果你坚持积极的态度,你的可能值远高于 2.000.000.000 ;)
这不是 GUID
让我跳入以下内容
它使用TotalMilliseconds
fromEPOCH
和一组有效的字符。
这不会是全局唯一的,但对于它定义的实例来说是唯一的
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
更新:同样可以从Guid
as
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
它通过将Guid
Base64 编码为以下代码来工作
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
正如其他人所提到的,YouTube 在VideoId
技术上并不是 GUID,因为它本身并不是唯一的。
根据维基百科:
唯一键的总数为 2 128或 3.4×10 38。这个数字是如此之大,以至于同一数字随机生成两次的概率可以忽略不计。
YouTube 的独特性VideoId
由他们的生成器算法维护。
您可以编写自己的算法,也可以使用某种随机字符串生成器并利用UNIQUE CONSTRAINT
SQL 中的约束来强制其唯一性。
UNIQUE CONSTRAINT
首先,在您的数据库中创建一个:
ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);
然后,例如,生成一个随机字符串(来自 philipproplesch 的回答):
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
如果生成UrlId
的足够随机且足够长,您应该很少遇到 SQL 遇到重复时引发的异常UrlId
。在这种情况下,您可以轻松地处理 Web 应用程序中的异常。
从技术上讲,它不是指南。Youtube 有一个简单的随机字符串生成器,您可以使用一组允许的字符和一个随机数生成器在几分钟内完成它。
这可能不是最好的解决方案,但你可以这样做:
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
这个 id 可能不是全局唯一的。GUID 应该是全局唯一的,因为它们包含不应在其他地方出现的元素(生成 ID 的机器的 MAC 地址、生成 ID 的时间等)
如果您需要的是在您的应用程序中唯一的 ID,请使用数字喷泉 - 可能将该值编码为十六进制数字。每次你需要一个 id 时,从数字喷泉中获取它。
如果您有多个服务器分配 id,您可以获取一系列数字(几十或几千取决于您分配 id 的速度),这应该可以完成工作。一个 8 位十六进制数字将为您提供 40 亿个 id - 但您的第一个 id 会短得多。