[C#] Come creo un HashCode in .net (c #) per una stringa che è sicura da memorizzare in un database?


Answers

Ecco una reimplementazione del modo corrente. NET calcola il suo codice hash stringa per i sistemi a 64 bit . Questo non usa puntatori come il vero GetHashCode() , quindi sarà leggermente più lento, ma renderà più resiliente alle modifiche interne alla string , questo darà un codice hash più uniformemente distribuito rispetto alla versione di Jon Skeet che potrebbe risultare migliore tempi di ricerca nei dizionari.

public static class StringExtensionMethods
{
    public static int GetStableHashCode(this string str)
    {
        unchecked
        {
            int hash1 = 5381;
            int hash2 = hash1;

            for(int i = 0; i < str.Length && str[i] != '\0'; i += 2)
            {
                hash1 = ((hash1 << 5) + hash1) ^ str[i];
                if (i == str.Length - 1 || str[i+1] == '\0')
                    break;
                hash2 = ((hash2 << 5) + hash2) ^ str[i+1];
            }

            return hash1 + (hash2*1566083941);
        }
    }
}
Question

Per citare linee guida e regole per GetHashCode di Eric Lippert:

Regola: i consumatori di GetHashCode non possono fare affidamento sulla loro stabilità nel tempo o attraverso le appdomain

Supponiamo che tu abbia un oggetto Cliente che abbia una serie di campi come Nome, Indirizzo e così via. Se si effettuano due tali oggetti con esattamente gli stessi dati in due processi diversi, non è necessario restituire lo stesso codice hash. Se effettui un tale oggetto martedì in un unico processo, spegnilo ed esegui nuovamente il programma mercoledì, i codici hash possono essere diversi.

Questo ha morso le persone in passato. La documentazione per System.String.GetHashCode rileva in modo specifico che due stringhe identiche possono avere codici hash diversi in diverse versioni del CLR e in effetti lo fanno. Non archiviare gli hash delle stringhe nei database e aspettarti che siano sempre gli stessi, perché non lo saranno.

Quindi qual è il modo corretto di creare un codice hash di una stringa che posso memorizzare in un database?

(Per favore dimmi che non sono il primo a lasciare questo bug nel software che ho scritto!)