In un'app, un utente può avviare la generazione di un codice alfanumerico a sei cifre (effettivamente eseguito tramite Web API). Il codice deve essere verificato su un database remoto per assicurarsi che sia univoco. Oltre alla diagnostica o alla registrazione, la tabella DB viene utilizzata solo dall'API Web e da un processo Web di Azure che elimina i codici scaduti.
Nei miei test, le collisioni si sono verificate in media solo una volta in ~ 24K volte con un massimo di 85K e un minimo di 170. È quest'ultima che mi riguarda. Sebbene la tabella venga svuotata giornalmente dei codici scaduti, a un certo punto ci sarà una collisione. Sebbene improbabile, potrebbe accadere con pochissimi record nella tabella.
Vale la pena notare che a causa dei requisiti esterni, il codice è limitato a sei caratteri da AEFGHJKLPQRSTUWXYZ123456789.
Una soluzione semplicistica sarebbe quella di continuare a generare la generazione / controllo fino alla creazione di un codice univoco. Con ogni probabilità, ciò significherebbe solo 1-2 iterazioni. Ma non c'è garanzia. E certamente non può funzionare senza impedimenti.
Il prossimo passo sarebbe mettere un limite - diciamo 5 tentativi - attraverso un semplice ciclo. Questo può essere abbastanza di una soluzione. Nonostante la preoccupazione che l'utente sarebbe frustrato se alla fine fallisce, se lo fa c'è probabilmente abbastanza sbagliato con il sistema generale per rovinare comunque l'esperienza dell'utente.
Ho un buon codice backoff esponenziale quindi, anche se questo non è un problema di rete (anche una preoccupazione), può aiutare a incorporarlo nello schema dei tentativi. In realtà, quella potrebbe essere una bella soluzione catch-all. Considerando 5 ritardi temporali crescenti nel tentativo di riprovare, ciò consentirebbe a entrambe le possibilità per il codice logico di superare le possibilità di una collisione e di mitigare l'introduzione di maggiore stress sulle risorse di rete.
Qualsiasi suggerimento / osservazione sarebbe apprezzato.
FYI, questo è il codice utilizzato per generare i codici:
/// <summary>
/// Generates a randomized alphanumeric code
/// </summary>
/// <param name="strLength">e.g. 6 chars</param>
/// <param name="charSet">e.g. AEFGHJKLPQRSTUWXYZ123456789</param>
/// <returns>string of the specified length</returns>
public static string GenerateCode(int strLength, string charSet)
{
var chars = charSet.ToCharArray();
var data = new byte[1];
var crypto = new RNGCryptoServiceProvider();
crypto.GetNonZeroBytes(data);
data = new byte[strLength];
crypto.GetNonZeroBytes(data);
var result = new StringBuilder(strLength);
foreach (var b in data)
{
result.Append(chars[b % (chars.Length)]);
}
return result.ToString();
}