生成一个在合理时间内不会重复的唯一数字的方法



我正在与远程web服务集成/测试,即使它是"QA"端点,它仍然在每次调用上强制执行一个唯一的电子邮件地址。

我可以想到DateTime.Now.Ticks(例如634970372342724417)和Guid.NewGuid(),但它们都不能合并为最多20个字符的电子邮件(或者它们可以吗?)。

我想向文件中写入一个包含最后使用的数字的数字,然后使用email1@x.com, email2@x.com, etc...并不难,但如果我能避免持久状态,我总是这样做。

有没有人有一个技巧或算法,可以给出一个短长度的"guid",它在相当长的时间段(比如一年)内是唯一的,我可以将其用于我的电子邮件地址,最大长度为20个字符,其中(guid的最大长度)=14=20-长度为"@x.com"?

如果您假设不会在同一个"tick"生成两个电子邮件地址,那么您确实可以使用tick来生成电子邮件地址。

然而,如果ticks是一个64位的数字,并且您写出了这个数字,那么您最终会得到20多个字符。

诀窍是使用不同的方案对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);

收益率:

Gq1rNzbezwg

如果您从日期时间中获得以下数字,您应该能够使其工作。。。Soemthing like:

DateTime.Now.ToString("yyMMddHHmmssff");

这是16个字符,剩下4个作为您需要的其他前缀。

因此,2013年2月21日,大约10:21将是"130321102142",下一个将是"13012102169",等等…

看看http://msdn.microsoft.com/en-us/library/zdtaw1bw.aspx有关日期时间格式的更多详细信息。

由于您在每次调用之间至少指定了1秒,因此这应该可以工作:

DateTime.Now.ToString("yyyyMMddHHmmss");

正好是14个字符。

只是添加。。。如果您只想使用记号中的数字,可以使用substring,例如:

int onlyThisAmount = 20;
string ticks = DateTime.Now.Ticks.ToString();
ticks = ticks.Substring(ticks.Length - onlyThisAmount);
    /// <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');
    }

在我的情况下,我需要创建一个唯一的参考号,第一个字符是唯一的,最多20个字符。也许你可以使用下面的函数,它允许你在一个刻度内创建9999个唯一的数字。(包括零)

当然,您可以创建自己的实现,而不需要第一个字符和20个的最大字符数

    public async Task<string> GeneratePatientNumberAsync()
    {
        var random = new Random();
        var chars = DateTime.Now.Ticks + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789" + DateTime.Now.Ticks;
        return new string(Enumerable.Repeat(chars, 5)
            .Select(s => s[random.Next(s.Length)]).ToArray());
    }

最新更新