ti-enxame.com

Maneira de gerar um número único que não se repete em um tempo razoável?

Estou integrando/testando com um serviço da Web remoto e, mesmo sendo o ponto de extremidade "QA", ele ainda impõe um endereço de e-mail exclusivo na chamada every.

Posso pensar em DateTime.Now.Ticks (Por exemplo, 634970372342724417) e Guid.NewGuid(), mas nenhum desses itens pode ser fundido em um e-mail com no máximo 20 caracteres (ou podem?).

Suponho que não seja tão difícil escrever para um arquivo um número que contenha o último número usado e use [email protected], [email protected], etc..., Mas se eu puder evitar o estado persistente, sempre o faço.

Alguém tem um truque ou algoritmo que fornece um "guid" de curta duração exclusivo para um período de tempo razoavelmente longo (digamos um ano) que eu poderia usar para meus endereços de e-mail de no máximo 20 caracteres com (comprimento máximo de guid) = 14 = 20 - comprimento de "@ x.com"?

13
Aaron Anodide

Se você presumir que não gerará dois endereços de email no mesmo 'tick', poderá usá-los para gerar um endereço de email.

No entanto, se ticks for um número de 64 bits e você escrever esse número, terá mais de 20 caracteres.

O truque é codificar seu número de 64 bits usando um esquema diferente. Suponha que você possa usar os 26 caracteres do alfabeto ocidental + 10 dígitos. Isso torna 36 caracteres possíveis. Se você usar 5 bits, poderá representar 32 caracteres. Isso deve ser o suficiente. Pegue os 64 bits e divida-os em grupos de 5 bits (64/5 é cerca de 13 grupos). Traduzir a cada 5 bits para um caractere. Dessa forma, você acaba com 13 caracteres e ainda pode adicionar um caractere na frente dele).

long ticks = DateTime.Now.Ticks;
byte[] bytes = BitConverter.GetBytes(ticks);
string id = Convert.ToBase64String(bytes)
                        .Replace('+', '_')
                        .Replace('/', '-')
                        .TrimEnd('=');
Console.WriteLine (id);

Rendimentos:

Gq1rNzbezwg
20
Patrick

Como você especificou pelo menos 1 segundo entre cada chamada, isso deve funcionar:

DateTime.Now.ToString("yyyyMMddHHmmss");

são exatamente 14 caracteres.

12
Abdusalam Ben Haj

Se você obtiver os seguintes dígitos da data e hora, poderá fazê-lo funcionar ...

DateTime.Now.ToString("yyMMddHHmmssff");

que tem 16 caracteres, deixando 4 para outro prefixo conforme necessário.

Portanto, em 21 de fevereiro de 2013, aproximadamente às 10:21, seria "130321102142" e o próximo seria "130321102169", etc ...

Dê uma olhada em http://msdn.Microsoft.com/en-us/library/zdtaw1bw.aspx para obter mais detalhes sobre a formatação de data e hora.

10
EtherDragon
    /// <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');
    }

No meu caso, eu precisava criar um número de referência exclusivo com um primeiro caractere exclusivo e um máximo de 20 caracteres. Talvez você possa usar a função abaixo, pois permite criar 9999 números únicos em um único tique. (zero incluído)

Claro que você pode criar sua própria implementação sem o primeiro caractere e a contagem máxima de 20 caracteres.

0
Martijn Willegers

Apenas para adicionar ... Se você deseja usar o número apenas de ticks, pode usar substring, por exemplo:

int onlyThisAmount = 20;
string ticks = DateTime.Now.Ticks.ToString();
ticks = ticks.Substring(ticks.Length - onlyThisAmount);
0
Michel Ayres