我需要在.NET中使用一个唯一标识符(由于太长,无法使用GUID)。
人们认为这里使用的算法是一个好的选择,还是您有其他建议?
我需要在.NET中使用一个唯一标识符(由于太长,无法使用GUID)。
人们认为这里使用的算法是一个好的选择,还是您有其他建议?
这是一个不错的方法 - http://www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx
还有一个方法可以参考:类似于YouTube的GUID
你可以使用Base64:
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
那会生成一个类似于E1HKfn68Pkms5zsZsvKONw==的字符串。由于GUID始终为128位,因此您可以省略您知道将始终存在于末尾的==,这将给您一个22个字符长的字符串。虽然这不如YouTube短。我使用与Dor Cohen类似的方法,但删除了一些特殊字符:
var uid = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", "");
这将仅输出字母数字字符。UID(唯一标识符)的长度不能保证始终相同。以下是示例运行:
vmKo0zws8k28fR4V4Hgmw
TKbhS0G2V0KqtpHOU8e6Ug
rfDi1RdO0aQHTosh9dVvw
3jhCD75fUWjQek8XRmMg
CQUg1lXIXkWG8KDFy7z6Ow
bvyxW5aj10OmKA5KMhppw
pIMK8eq5kyvLK67xtsIDg
VX4oljGWpkSQGR2OvGoOQ
NOHBjUUHv06yIc7EvotRg
iMniAuUG9kiGLwBtBQByfg
var ticks = new DateTime(2016,1,1).Ticks;
var ans = DateTime.Now.Ticks - ticks;
var uniqueId = ans.ToString("x");
保留一个基准日期(在此示例中为2016年1月1日),从该日期开始生成这些ID。这将使您的ID更小。
生成的编号:3af3c14996e54
DateTime
对象的 milliseconds
始终为0。 - Teejay简单易用的包。我将其用于生成临时请求ID。
https://www.nuget.org/packages/shortid
https://github.com/bolorundurowb/shortid
使用了 System.Random
。
string id = ShortId.Generate();
// id = KXTR_VzGVUoOY
如果你希望通过指定数字、特殊字符和长度来控制生成的ID类型,请调用Generate方法并传递三个参数:第一个布尔值表示是否需要数字,第二个布尔值表示是否需要特殊字符,最后一个数字表示您的长度偏好。string id = ShortId.Generate(true, false, 12);
// id = VvoCDPazES_w
如果仅仅移除连字符就足够了,以下内容或许对您有帮助:
Guid.NewGuid().ToString("n")
5db4cee3bfd8436395d37fca2d48d5b3
82fac271c76148a3a0667c00a5da990d
对于我的本地应用程序,我使用基于时间的方法:
/// <summary>
/// Returns all ticks, milliseconds or seconds since 1970.
///
/// 1 tick = 100 nanoseconds
///
/// Samples:
///
/// Return unit value decimal length value hex length
/// --------------------------------------------------------------------------
/// ticks 14094017407993061 17 3212786FA068F0 14
/// milliseconds 1409397614940 13 148271D0BC5 11
/// seconds 1409397492 10 5401D2AE 8
///
/// </summary>
public static string TickIdGet(bool getSecondsNotTicks, bool getMillisecondsNotTicks, bool getHexValue)
{
string id = string.Empty;
DateTime historicalDate = new DateTime(1970, 1, 1, 0, 0, 0);
if (getSecondsNotTicks || getMillisecondsNotTicks)
{
TimeSpan spanTillNow = DateTime.UtcNow.Subtract(historicalDate);
if (getSecondsNotTicks)
id = String.Format("{0:0}", spanTillNow.TotalSeconds);
else
id = String.Format("{0:0}", spanTillNow.TotalMilliseconds);
}
else
{
long ticksTillNow = DateTime.UtcNow.Ticks - historicalDate.Ticks;
id = ticksTillNow.ToString();
}
if (getHexValue)
id = long.Parse(id).ToString("X");
return id;
}
在数据库中,IDENTITY值应该是唯一的,但您应该意识到其限制...例如,它使得批量数据插入基本上不可能,如果您正在处理大量记录,则会减慢速度。
您还可以使用日期/时间值。我见过几个数据库将日期/时间用作主键,虽然这不是非常干净的方法,但它确实有效。如果您控制插入操作,则可以在代码中有效地保证值是唯一的。
参考其他方案,这里是我的解决方案,可以提供一个不同的编码GUID,它是URL(和Docker)安全的,不会丢失任何信息:
Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("=", "").Replace("+", "-").Replace("/", "_");
示例输出如下:
BcfttHA780qMdHSxSBoZFA
_4p5srPgOE2f25T_UnoGLw
H9xR_zdfm0y-zYjdR3NOig
22个字符,URL安全,并保持Guid的唯一性。
// Our url safe, base 64 alphabet:
const string alphabet = "-_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Sanitized Guid string. Preserve the last two hex chars
var guidStr = "929F7C4D4B2644E1A122A379C02D6345";
var lastTwo = guidStr.Substring(30, 2);
string shortGuid = "";
// Iterate over the ten groups of 3 hex chars: 929 F7C 4D4 B26 44E 1A1 22A 379 C02 D63
for (var i = 0; i < 10; i++)
{
var hex = guidStr.Substring(i*3, 3); // Get the next 3 hex chars
var x = Convert.ToInt32(hex, 16); // Convert to int
shortGuid += $"{alphabet[x/64]}{alphabet[x%64]}"; // Lookup the two-digit base64 value
}
shortGuid += lastTwo; // Don't forget the last two
Console.WriteLine(shortGuid);
输出:
yDXWhiGAfc4v6EbTK0Px45