2013-02-21 9 views
11

Sto integrando/testando con un servizio Web remoto e anche se è l'endpoint "QA", applica comunque un indirizzo email univoco su ogni chiamata.Modo per generare un numero univoco che non si ripete in un tempo ragionevole?

Posso pensare a DateTime.Now.Ticks (ad esempio 634970372342724417) e Guid.NewGuid(), ma nessuno di questi può essere riunito in un'e-mail con max. 20 caratteri (o possono?).

Suppongo che non sia così difficile scrivere su un file un numero che contiene l'ultimo numero utilizzato e quindi utilizzare [email protected], [email protected], etc... ma se riesco a evitare lo stato persistente lo faccio sempre.

Qualcuno ha un trucco o un algoritmo che fornisce qualcosa di "guida" di breve durata che è unico per un periodo di tempo ragionevolmente lungo (diciamo un anno) che potrei usare per i miei indirizzi e-mail di lunghezza massima di 20 caratteri con (lunghezza massima di guida) = 14 = 20 - lunghezza di "@ x.com"?

+0

Quanto spesso si inviano le richieste? – AbZy

+0

Non è un test di carico. C'è almeno un secondo tra le chiamate –

+0

http://stackoverflow.com/questions/4421442/generate-8-digit-uinque-id-in-c-sharp In particolare la risposta di Jon Skeet potrebbe essere utile per il tuo caso –

risposta

15

Se si assume che non si generano due indirizzi e-mail allo stesso "segno di spunta", è possibile utilizzare i segni di graduazione per generare un indirizzo e-mail.

Tuttavia, se le zecche sono un numero a 64 bit e si scrive quel numero, si otterranno più di 20 caratteri.

Il trucco è codificare il numero a 64 bit utilizzando uno schema diverso. Supponiamo che tu possa usare i 26 caratteri dell'alfabeto occidentale + 10 cifre. Questo rende 36 possibili caratteri. Se prendi 5 bit, puoi rappresentare 32 caratteri. Questo dovrebbe essere abbastanza Prendere i 64 bit e dividerli in gruppi di 5 bit (64/5 è di circa 13 gruppi). Trasforma ogni 5 bit in un carattere. In questo modo finirai con 13 personaggi, e puoi ancora aggiungere un personaggio di fronte ad esso).

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

Resa:

Gq1rNzbezwg 
+0

Sono sul punto di far funzionare la tua risposta convertendo ticks in base64 .. devo solo capire cosa fare con '+' e '/' ... –

+0

ahh .. li convertirò in ' _ 'e' -'... –

+1

ho modificato la tua risposta per contenere il codice che ho elaborato sul tuo suggerimento .. –

10

Dal momento che è stato specificato almeno 1 secondo tra ogni chiamata, questo dovrebbe funzionare:

DateTime.Now.ToString("yyyyMMddHHmmss"); 

sue esattamente 14 caratteri.

+0

Questo sarebbe limitato a una e-mail unica al secondo attraverso ... –

+1

@VenomFangs sì, vedere il commento OP sulla domanda. 'Non è un test di carico. C'è almeno un secondo tra le chiamate – AbZy

+1

buona chiamata mi è mancato. –

6

Se si ottiene i seguenti cifre da data-tempo, si dovrebbe essere in grado di farlo funzionare ... Soemthing come:

DateTime.Now.ToString("yyMMddHHmmssff"); 

che è di 16 caratteri, lasciando 4 per qualche altro prefisso hai bisogno.

Quindi, Feb 21, 2013, a circa 10:21 sarebbe "130.321.102.142" e la prossima sarebbe "130.321.102.169", ecc ...

Dai un'occhiata alla http://msdn.microsoft.com/en-us/library/zdtaw1bw.aspx per maggiori dettagli sulla formattazione datetime .

+0

+1 per l'utilizzo di yy e ff. Ma c'è una piccola possibilità che ci siano duplicati se usi hh e non HH. – AbZy

+1

Sì, era un esempio di codice non testato. Quando possibile mi piace buttare questo tipo di cose nel mio progetto di laboratorio solo per assicurarmi che funzionino come pubblicizzato. Indipendentemente da ciò - risposta aggiornata all'utente HH. – EtherDragon

0

solo aggiungere ... Se si desidera utilizzare il numero solo dalle zecche, è possibile utilizzando substring, ad esempio:

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

Nel mio caso ho dovuto creare un numero di riferimento univoco con un primo carattere unico e un massimo di 20 caratteri.Forse puoi usare la funzione qui sotto, ti permette di creare 9999 numeri univoci entro un tick. (Incluso lo zero)

Naturalmente è possibile creare una propria implementazione, senza il primo carattere e numero massimo di caratteri di 20