2009-02-13 8 views

Antwort

20

Ich nehme an, dass Sie dies tun, weil Sie den Wert anderswo speichern und dagegen vergleichen müssen. Daher kann die Antwort von Zach (obwohl sie völlig korrekt ist) Probleme verursachen, da der Vertrag für String.GetHashCode() explizit seinen Änderungsbereich enthält.

Also hier ist eine feste und in anderen Sprachen leicht wiederholbare Version.

Ich nehme an, dass Sie zur Kompilierzeit die Anzahl der verfügbaren Dezimalstellen wissen. Dies basiert auf dem Jenkins One At a Time Hash (wie implementiert und exhaustively tested von Bret Mulvey), als solches hat es ein hervorragendes Lawinenverhalten (eine Änderung von einem Bit in der Eingabe propagiert zu allen Bits der Ausgabe), was etwas bedeutet faul Moduloreduktion in Bits am Ende ist kein schwerwiegender Fehler für die meisten Anwendungen (auch wenn man mit komplexeren Verhalten besser machen könnte)

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

Code fehlt ein Semikolon in der letzten Codezeile. Versucht zu bearbeiten, aber SO erfordert 6 Änderungen. –

6

Einfacher Ansatz (beachten Sie, dass dies platform-dependent):

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

Dies wird den gleichen Wert für zwei verschiedene Strings mit dem gleichen Inhalt – joshperry

+0

nicht machen @ joshperry: Danke, ich habe einen Disclaimer in die Antwort eingefügt. –

+1

@joshperry - ähm, ja, es wird ... es ist nicht garantiert, dass zwischen den Versionen von .NET dasselbe bleibt. Allerdings kann * no * hash ** garantieren ** geändert werden, wenn sich der Eingabetext ändert - Kollisionen, obwohl unwahrscheinlich, werden passieren (sehr, sehr, sehr selten). –

-1

Verwenden System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHash einen MD5-Hash zu bekommen, gestutzt auf die gewünschte Länge.

Verwandte Themen