2009-02-13 20 views

risposta

20

Suppongo che lo stiate facendo perché è necessario memorizzare il valore altrove e confrontarlo con esso. Pertanto, la risposta di Zach (anche se del tutto corretta) potrebbe causare problemi in quanto il contratto per String.GetHashCode() è esplicito sul suo ambito di modifica.

Ecco quindi una versione fissa e facilmente ripetibile in altre lingue.

Presumo che al momento della compilazione sia possibile conoscere il numero di cifre decimali disponibili. Questo è basato sul Jenkins One At a Time Hash (come implementato e exhaustively tested di Bret Mulvey), come tale ha un eccellente comportamento di valanga (un cambiamento di un bit nell'input si propaga su tutti i bit dell'output) il che significa che riduzione modulo pigro bit alla fine non è un grave difetto per gli usi più (anche se si potrebbe fare meglio con un comportamento più complesso)

const int MUST_BE_LESS_THAN = 100000000; // 8 decimal digits 

public int GetStableHash(string s) 
{ 
    uint hash = 0; 
    // if you care this can be done much faster with unsafe 
    // using fixed char* reinterpreted as a byte* 
    foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s)) 
    { 
     hash += b; 
     hash += (hash << 10); 
     hash ^= (hash >> 6);  
    } 
    // final avalanche 
    hash += (hash << 3); 
    hash ^= (hash >> 11); 
    hash += (hash << 15); 
    // helpfully we only want positive integer < MUST_BE_LESS_THAN 
    // so simple truncate cast is ok if not perfect 
    return (int)(hash % MUST_BE_LESS_THAN) 
} 
+0

Il codice manca di punto e virgola sull'ultima riga di codice. Ho cercato di modificare ma SO richiede 6 modifiche. –

6

approccio semplice (si noti che questo è platform-dependent):

int shorthash = "test".GetHashCode() % 100000000; // 8 zeros 
if (shorthash < 0) shorthash *= -1; 
+0

Questo non renderà lo stesso valore per due diverse stringhe con lo stesso contenuto – joshperry

+0

@ joshperry: Grazie, ho aggiunto un disclaimer nella risposta. –

+1

@joshperry - er, sì lo farà .. non è garantito che rimanga lo stesso tra le versioni .NET. Tuttavia, * no * hash può ** garantire ** di cambiare quando cambia il testo di input - le collisioni, anche se improbabili, avverranno (molto, molto, molto raramente). –

-1

Usa System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHash per ottenere un hash MD5, tronca alla lunghezza desiderata.

Problemi correlati