Ich habe ein 16-Byte-Array von MD5 JAVA-Methode. Ich möchte es in einen Long-Wert konvertieren, um es als Hashkey zu verwenden. Ich lese eine bitweise XOR die Bits auf 64 ist eine gute Idee... dann howto erhalten eine lange aus, dass? vollständigen Code-Beispiel von XOR und cvt zu lang bitte.
Antworten
Zu viele Anzeigen?Die beste Lösung, die ich gefunden habe (basierend auf meinen Bedürfnissen... Mischung aus Geschwindigkeit und guter Hash-Funktion) ist Googles CityHash . Die Eingabe kann ein beliebiges Byte-Array einschließlich eines MD5-Ergebnisses sein, und die Ausgabe ist ein vorzeichenloser 64-Bit-Long.
CityHash hat eine sehr gute, aber nicht perfekte Hash-Verteilung und ist sehr schnell.
Ich habe CityHash in einer halben Stunde von C++ nach C# portiert. Eine Java-Portierung sollte auch einfach sein.
Eine einfache XOR-Verknüpfung der Bits ergibt keine so gute Verteilung (obwohl das zugegebenermaßen sehr schnell geht).
Ich kenne mich mit Java nicht gut genug aus, um Ihnen genau sagen zu können, wie man einen Long aus einem Byte-Array auffüllt (vielleicht gibt es ein gutes Hilfsmittel, mit dem ich nicht vertraut bin, oder ich habe einige Details der Arithmetik in Java falsch verstanden). Im Wesentlichen werden Sie jedoch Folgendes tun wollen etwas wie diese:
long a = md5[0] * 256 * md5[1] + 256 * 256 * md5[2] + 256 * 256 * 256 * md5[3];
long b = md5[4] * 256 * md5[5] + 256 * 256 * md5[6] + 256 * 256 * 256 * md5[7];
long result = a ^ b;
Beachten Sie, dass ich nicht versucht habe, mich mit endianness . Wenn Sie sich nur für einen konsistenten Hash-Wert interessieren, sollte die Endianness jedoch keine Rolle spielen.
Guava hat einige sehr schöne Hashing-Fähigkeiten :
Hashing.md5().hashString(s).asLong();
Ich glaube, die oben ist eigentlich CityHash, aber unabhängig davon wird es Hash-Längen, die Sie für was auch immer Ihre Hashing-Bedürfnisse verwenden können generieren. (Ich habe @Eric J. Java-Code versucht und es sieht aus wie CityHash 32).
Nur um das klarzustellen: Jeder Unterabschnitt eines kryptografischen Digests hat viele der kryptografischen Eigenschaften des Digests nicht mehr, insbesondere gelten diese Eigenschaften nicht mehr:
- Umkehrwiderstand (Finden eines X, das H(X) erfüllt)
- Kollisionswiderstand (Finden eines X, Y, so dass H(X) = H(Y))
- Zufallsverteilung über den Bereich der möglichen Ausgaben