C# .NET 短唯一标识符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9278909/
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
.NET Short Unique Identifier
提问by Noel
采纳答案by Dor Cohen
This one a good one - http://www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx
and also here YouTube-like GUID
还有这里 类似 YouTube 的 GUID
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 David
IDENTITY values should be unique in a database, but you should be aware of the limitations... for example, it makes bulk data inserts basically impossible which will slow you down if you're working with a very large number of records.
IDENTITY 值在数据库中应该是唯一的,但您应该注意局限性……例如,它使批量数据插入基本上不可能,如果您正在处理大量记录,这会减慢您的速度。
You may also be able to use a date/time value. I've seen several databases where they use the date/time to be the PK, and while it's not super clean - it works. If you control the inserts, you can effectively guarantee that the values will be unique in code.
您也可以使用日期/时间值。我见过几个数据库,他们使用日期/时间作为 PK,虽然它不是超级干净 - 它可以工作。如果您控制插入,则可以有效地保证这些值在代码中是唯一的。
回答by Pollitzer
For my local app I'm using this time based approach:
对于我的本地应用程序,我使用的是基于时间的方法:
/// <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;
}
回答by Pompair
Guid.NewGuid().ToString().Split('-').First()
回答by Christian Specht
As far as I know, just stripping off a part of a GUID isn't guaranteed to be unique- in fact, it's far from being unique.
据我所知,仅仅剥离 GUID 的一部分并不能保证是唯一的- 事实上,它远非唯一。
The shortest thing that I know that guarantees global uniqueness is featured in this blog post by Jeff Atwood. In the linked post, he discusses multiple ways to shorten a GUID, and in the end gets it down to 20 bytes via Ascii85 encoding.
Jeff Atwood在这篇博文中介绍了我所知道的能保证全局唯一性的最短的东西。在链接的帖子中,他讨论了缩短 GUID 的多种方法,最后通过Ascii85 编码将其缩减为 20 个字节。
However, if you absolutely need a solution that's no longer than 15 bytes, I'm afraid you have no other choice than to use something which is not guaranteed to be globally unique.
但是,如果您绝对需要一个不超过 15 个字节的解决方案,恐怕您别无选择,只能使用不能保证全球唯一的东西。
回答by Diogo
I use Guid.NewGuid().ToString().Split('-')[0], it gets the first item from the array separated by the '-'. Its enough to represent a unique key.
我使用Guid.NewGuid().ToString().Split('-')[0],它从由“-”分隔的数组中获取第一项。它足以代表一个唯一的键。
回答by ur3an0
here my solution, is not safe for concurrency, no more of 1000 GUID's per seconds and thread safe.
在这里,我的解决方案对于并发来说是不安全的,每秒不超过 1000 个 GUID,并且线程安全。
public static class Extensors
{
private static object _lockGuidObject;
public static string GetGuid()
{
if (_lockGuidObject == null)
_lockGuidObject = new object();
lock (_lockGuidObject)
{
Thread.Sleep(1);
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var epochLong = Convert.ToInt64((DateTime.UtcNow - epoch).TotalMilliseconds);
return epochLong.DecimalToArbitrarySystem(36);
}
}
/// <summary>
/// Converts the given decimal number to the numeral system with the
/// specified radix (in the range [2, 36]).
/// </summary>
/// <param name="decimalNumber">The number to convert.</param>
/// <param name="radix">The radix of the destination numeral system (in the range [2, 36]).</param>
/// <returns></returns>
public static string DecimalToArbitrarySystem(this long decimalNumber, int radix)
{
const int BitsInLong = 64;
const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (radix < 2 || radix > Digits.Length)
throw new ArgumentException("The radix must be >= 2 and <= " + Digits.Length.ToString());
if (decimalNumber == 0)
return "0";
int index = BitsInLong - 1;
long currentNumber = Math.Abs(decimalNumber);
char[] charArray = new char[BitsInLong];
while (currentNumber != 0)
{
int remainder = (int)(currentNumber % radix);
charArray[index--] = Digits[remainder];
currentNumber = currentNumber / radix;
}
string result = new String(charArray, index + 1, BitsInLong - index - 1);
if (decimalNumber < 0)
{
result = "-" + result;
}
return result;
}
code not optimized, just sample!.
代码未优化,只是示例!。
回答by Chris Phan
If your app dont have a few MILLIION people, using that generate short unique string at the SAME MILLISECOND, you can think about using below function.
如果您的应用程序没有几百万人,使用它在同一毫秒内生成短的唯一字符串,您可以考虑使用以下功能。
private static readonly Object obj = new Object();
private static readonly Random random = new Random();
private string CreateShortUniqueString()
{
string strDate = DateTime.Now.ToString("yyyyMMddhhmmssfff");
string randomString ;
lock (obj)
{
randomString = RandomString(3);
}
return strDate + randomString; // 16 charater
}
private string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxy";
var random = new Random();
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
change yyyy to yy if you just need to use your app in next 99 year.
Update 20160511: Correct Random function
- Add Lock object
- Move random variable out of RandomString function
Ref
如果您只需要在未来 99 年使用您的应用程序,请将 yyyy 更改为 yy。
更新 20160511:更正随机函数
- 添加锁定对象
- 将随机变量移出 RandomString 函数
Ref
回答by hazHyman
I know it's quite far from posted date... :)
我知道它离发布日期很远...... :)
I have a generator which produces only 9 Hexa characters, eg: C9D6F7FF3, C9D6FB52C
我有一个只产生9 个十六进制字符的生成器,例如:C9D6F7FF3、C9D6FB52C
public class SlimHexIdGenerator : IIdGenerator
{
private readonly DateTime _baseDate = new DateTime(2016, 1, 1);
private readonly IDictionary<long, IList<long>> _cache = new Dictionary<long, IList<long>>();
public string NewId()
{
var now = DateTime.Now.ToString("HHmmssfff");
var daysDiff = (DateTime.Today - _baseDate).Days;
var current = long.Parse(string.Format("{0}{1}", daysDiff, now));
return IdGeneratorHelper.NewId(_cache, current);
}
}
static class IdGeneratorHelper
{
public static string NewId(IDictionary<long, IList<long>> cache, long current)
{
if (cache.Any() && cache.Keys.Max() < current)
{
cache.Clear();
}
if (!cache.Any())
{
cache.Add(current, new List<long>());
}
string secondPart;
if (cache[current].Any())
{
var maxValue = cache[current].Max();
cache[current].Add(maxValue + 1);
secondPart = maxValue.ToString(CultureInfo.InvariantCulture);
}
else
{
cache[current].Add(0);
secondPart = string.Empty;
}
var nextValueFormatted = string.Format("{0}{1}", current, secondPart);
return UInt64.Parse(nextValueFormatted).ToString("X");
}
}
回答by Basheer AL-MOMANI
you can use
您可以使用
code = await UserManager.GenerateChangePhoneNumberTokenAsync(input.UserId, input.MobileNumber);
its 6nice characters only, 599527,143354
它6只有漂亮的字符599527,,143354
and when user virify it simply
当用户简单地对其进行病毒化时
var result = await UserManager.VerifyChangePhoneNumberTokenAsync(input.UserId, input.Token, input.MobileNumber);
hope this help you
希望这对你有帮助

