C# 生成在合理时间内不重复的唯一编号的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15009423/
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
Way to generate a unique number that does not repeat in a reasonable time?
提问by Aaron Anodide
I'm integrating/testing with a remote web service and even though it's the "QA" endpoint, it still enforces a unique email address on everycall.
我正在与远程 Web 服务集成/测试,即使它是“QA”端点,它仍然在每次调用时强制执行唯一的电子邮件地址。
I can think of DateTime.Now.Ticks
(e.g. 634970372342724417) and Guid.NewGuid()
, but neither of those can be coalesced into an email with max. 20 chars (or can they?).
我可以想到DateTime.Now.Ticks
(例如 634970372342724417) 和Guid.NewGuid()
,但是这两个都不能合并到最大的电子邮件中。20 个字符(或者可以吗?)。
I suppose it's not that hard to write out to a file a number that contains the last number used and then use [email protected], [email protected], etc...
but if I can avoid persisting state I always do.
我想将一个包含最后使用的数字然后使用的数字写入文件并不难,[email protected], [email protected], etc...
但如果我可以避免持久状态,我总是这样做。
Does anyone have a trick or an algorithm that gives something of a short length "guid" that is unique to a reasonably long time period (say a year) that I could use for my email addresses of max length 20 chars with (max length of guid) = 14 = 20 - length of "@x.com"?
有没有人有一个技巧或算法可以提供一个短长度的“guid”,它是相当长的时间段(比如一年)所独有的,我可以将它用于我的最大长度为 20 个字符的电子邮件地址(最大长度为guid) = 14 = 20 - “@x.com”的长度?
采纳答案by Patrick
If you assume that you will not generate two e-mail addresses at the same 'tick', then you can indeed use the ticks to generate an e-mail address.
如果您假设您不会在同一个“勾号”上生成两个电子邮件地址,那么您确实可以使用勾号来生成一个电子邮件地址。
However, if ticks is a 64-bit number, and you write out that number, you will end up with more than 20 characters.
但是,如果 ticks 是一个 64 位数字,并且您写出该数字,则最终会得到 20 个以上的字符。
The trick is to encode your 64-bit number using a different scheme. Assume that you can use the 26 characters from the western alphabet + 10 digits. This makes 36 possible characters. If you take 5 bits, you can represent 32 characters. That should be enough. Take the 64-bits and divide them in groups of 5 bits (64 /5 is about 13 groups). Translate every 5 bits to one character. That way you end up with 13 characters, and you can still add a character in front of it).
诀窍是使用不同的方案对您的 64 位数字进行编码。假设您可以使用西方字母表中的 26 个字符 + 10 个数字。这使得 36 个可能的字符。如果取 5 位,则可以表示 32 个字符。那应该就够了。取64位,分成5位一组(64/5大约是13组)。每 5 位转换为一个字符。这样你最终得到 13 个字符,你仍然可以在它前面添加一个字符)。
long ticks = DateTime.Now.Ticks;
byte[] bytes = BitConverter.GetBytes(ticks);
string id = Convert.ToBase64String(bytes)
.Replace('+', '_')
.Replace('/', '-')
.TrimEnd('=');
Console.WriteLine (id);
Yields:
产量:
Gq1rNzbezwg
回答by Abdusalam Ben Haj
Since you specified at least 1 second between each call, this should work :
由于您在每次调用之间指定了至少 1 秒,因此应该可以:
DateTime.Now.ToString("yyyyMMddHHmmss");
its exactly 14 characters.
它正好是 14 个字符。
回答by EtherDragon
If you get the following digits from your date-time, you should be able to make it work... Soemthing like:
如果你从你的日期时间得到以下数字,你应该能够让它工作...... Soemthing like:
DateTime.Now.ToString("yyMMddHHmmssff");
which is 16 characters, leaving 4 for some other prefix as you need.
这是 16 个字符,根据需要为其他一些前缀留下 4 个字符。
So, Feb 21, 2013, at approximately 10:21 would be "130321102142" and the next one would be "130321102169", etc...
因此,2013 年 2 月 21 日,大约 10:21 将是“130321102142”,下一个将是“130321102169”,等等......
Have a look at http://msdn.microsoft.com/en-us/library/zdtaw1bw.aspxfor more details on datetime formatting.
有关日期时间格式的更多详细信息,请查看http://msdn.microsoft.com/en-us/library/zdtaw1bw.aspx。
回答by Michel Ayres
Just to add... If you want to use number only from ticks, you can by using substring
, for example:
只是添加...如果您只想使用刻度线中的数字,您可以使用substring
,例如:
int onlyThisAmount = 20;
string ticks = DateTime.Now.Ticks.ToString();
ticks = ticks.Substring(ticks.Length - onlyThisAmount);
回答by Martijn Willegers
/// <summary>
/// Get a unique reference number.
/// </summary>
/// <returns></returns>
public string GetUniqueReferenceNumber(char firstChar)
{
var ticks = DateTime.Now.Ticks;
var ticksString = ticks.ToString();
var ticksSubString = ticksString.Substring((ticksString.Length - 15 > 0) ? ticksString.Length - 15 : 0);
if (this.currentTicks.Equals(ticks))
{
this.currentReference++;
if (this.currentReference >= 9999)
{
// Only when there are very fast computers.
System.Threading.Thread.Sleep(1);
}
return (firstChar + ticksSubString + this.currentReference.ToString("D4")).PadRight(20, '9');
}
this.currentReference = -1;
this.currentTicks = ticks;
return (firstChar + ticksSubString).PadRight(20, '9');
}
In my case I needed to create a unique reference number with a unique first character and a maximum of 20 characters. Maybe you can use the function below, it allows you to create 9999 unique numbers within one tick. (zero included)
就我而言,我需要创建一个唯一的参考编号,其中包含唯一的第一个字符和最多 20 个字符。也许您可以使用下面的功能,它可以让您在一个刻度内创建 9999 个唯一数字。(包括零)
Of course you can create your own implementation without the first character and maximum character count of 20
当然,您可以在没有第一个字符和最大字符数为 20 的情况下创建自己的实现