Gibt es eine Verschlüsselungsmethode, die eine Zeichenfolge beliebiger Länge annehmen und einen Hash mit weniger als 10 Zeichen erzeugen kann? Ich möchte einigermaßen eindeutige IDs erstellen, die jedoch nicht zufällig, sondern auf Nachrichteninhalten basieren.
Ich kann damit leben, die Nachrichten auf ganzzahlige Werte zu beschränken, wenn Zeichenfolgen beliebiger Länge unmöglich sind. In diesem Fall darf der Hash jedoch nicht für zwei aufeinanderfolgende Ganzzahlen ähnlich sein.
encryption
uniqueidentifier
rath3r
quelle
quelle
Antworten:
Sie können jeden allgemein verfügbaren Hash-Algorithmus (z. B. SHA-1) verwenden, wodurch Sie ein etwas längeres Ergebnis erzielen als erforderlich. Schneiden Sie das Ergebnis einfach auf die gewünschte Länge ab, was gut genug sein kann.
Zum Beispiel in Python:
quelle
hash(a)
kollidiert mithash(b)
dannbase64(hash(a))
auch kollidiert mitbase64(hash(b))
.sha1
kollidiert, aber dies ist eine andere Geschichte). Wenn Sie einen Hash mit 10 Zeichen haben, erhalten Sie eine höhere Entropie, wenn er mitbase64
vsbase16
(oder hex) codiert ist . Wie höher? Mitbase16
erhalten Sie 4 Bits pro Zeichen, mitbase64
dieser Figur ist 6bits / char. Insgesamt hat ein 10-Zeichen- "Hex" -Hash 40 Bit Entropie, während ein base64 60 Bit hat. Es ist also etwas widerstandsfähiger, sorry wenn ich nicht super klar war.Wenn Sie keinen Algorithmus benötigen, der stark gegen absichtliche Änderungen ist, habe ich einen Algorithmus namens adler32 gefunden , der ziemlich kurze Ergebnisse (~ 8 Zeichen) liefert. Wählen Sie es hier aus der Dropdown-Liste aus, um es auszuprobieren:
http://www.sha1-online.com/
quelle
Sie müssen den Inhalt hashen, um eine Übersicht zu erhalten. Es sind viele Hashes verfügbar, aber 10 Zeichen sind für die Ergebnismenge ziemlich klein. Vor langer Zeit verwendeten die Leute CRC-32, das einen 33-Bit-Hash erzeugt (im Grunde 4 Zeichen plus ein Bit). Es gibt auch CRC-64, der einen 65-Bit-Hash erzeugt. MD5, das einen 128-Bit-Hash (16 Bytes / Zeichen) erzeugt, wird für kryptografische Zwecke als fehlerhaft betrachtet, da zwei Nachrichten gefunden werden können, die denselben Hash haben. Es versteht sich von selbst, dass Sie jedes Mal, wenn Sie einen 16-Byte-Digest aus einer Nachricht beliebiger Länge erstellen, Duplikate erhalten. Je kürzer die Verdauung ist, desto größer ist das Kollisionsrisiko.
Ihre Sorge, dass der Hash für zwei aufeinanderfolgende Nachrichten (ob Ganzzahlen oder nicht) nicht ähnlich ist, sollte jedoch bei allen Hashes zutreffen. Selbst eine einzelne Bitänderung in der ursprünglichen Nachricht sollte zu einem völlig anderen resultierenden Digest führen.
Wenn Sie also etwas wie CRC-64 verwenden (und das Ergebnis mit Base-64 erstellen), sollten Sie in die Nachbarschaft gelangen, nach der Sie suchen.
quelle
Ich fasse nur eine Antwort zusammen, die für mich hilfreich war (unter Hinweis auf @ erasmospunks Kommentar zur Verwendung der Base-64-Codierung). Mein Ziel war es, eine kurze Saite zu haben, die größtenteils einzigartig war ...
Ich bin kein Experte, bitte korrigieren Sie dies, wenn es irgendwelche offensichtlichen Fehler gibt (in Python wieder wie die akzeptierte Antwort):
In
result
diesem Fall werden mehr als nur Hex-Zeichen verwendet (was Sie erhalten würden, wenn Sie es verwenden würdenhash.hexdigest()
), sodass es weniger wahrscheinlich ist, dass es zu einer Kollision kommt (das heißt, das Abschneiden sollte sicherer sein als bei einem Hex-Digest).Hinweis: Verwenden von UUID4 (zufällig). Weitere Typen finden Sie unter http://en.wikipedia.org/wiki/Universally_unique_identifier .
quelle
Sie können einen vorhandenen Hash-Algorithmus verwenden, der etwas Kurzes erzeugt, wie MD5 (128 Bit) oder SHA1 (160). Dann können Sie dies weiter verkürzen, indem Sie Abschnitte des Digests mit anderen Abschnitten XOR-verknüpfen. Dies erhöht die Wahrscheinlichkeit von Kollisionen, ist jedoch nicht so schlimm wie das einfache Abschneiden des Digests.
Sie können auch die Länge der Originaldaten als Teil des Ergebnisses angeben, um sie eindeutiger zu machen. Zum Beispiel würde das XORing der ersten Hälfte eines MD5-Digests mit der zweiten Hälfte zu 64 Bit führen. Fügen Sie 32 Bit für die Länge der Daten hinzu (oder weniger, wenn Sie wissen, dass diese Länge immer in weniger Bits passt). Dies würde zu einem 96-Bit-Ergebnis (12 Byte) führen, das Sie dann in eine 24-stellige Hex-Zeichenfolge umwandeln könnten. Alternativ können Sie die Base 64-Codierung verwenden, um sie noch kürzer zu machen.
quelle
Bei Bedarf können
"sub-10-character hash"
Sie den Fletcher-32- Algorithmus verwenden, der 8-Zeichen-Hash (32 Bit), CRC-32 oder Adler-32 erzeugt .CRC-32 ist um den Faktor 20% - 100% langsamer als Adler32.
Fletcher-32 ist etwas zuverlässiger als Adler-32. Es hat einen geringeren Rechenaufwand als die Adler-Prüfsumme: Fletcher vs Adler-Vergleich .
Ein Beispielprogramm mit einigen Fletcher-Implementierungen ist unten angegeben:
Ausgabe:
Stimmt mit Testvektoren überein :
Adler-32 hat eine Schwäche für Kurznachrichten mit einigen hundert Bytes, da die Prüfsummen für diese Nachrichten eine schlechte Abdeckung der 32 verfügbaren Bits aufweisen. Überprüfen Sie dies:
Der Adler32-Algorithmus ist nicht komplex genug, um mit vergleichbaren Prüfsummen zu konkurrieren .
quelle
Führen Sie dies einfach in einem Terminal aus (unter MacOS oder Linux):
8 Zeichen lang.
quelle
Sie können die Hash- Bibliothek für Python verwenden. Die Shake_128- und Shake_256- Algorithmen bieten Hashes variabler Länge. Hier ist ein Arbeitscode (Python3):
Beachten Sie, dass die Funktion mit einem Längenparameter x (Beispiel 5) einen Hashwert der Länge 2x zurückgibt .
quelle
Es ist jetzt 2019 und es gibt bessere Möglichkeiten. Nämlich xxhash .
quelle
Ich brauchte in letzter Zeit etwas in der Art einer einfachen String-Reduktionsfunktion. Grundsätzlich sah der Code ungefähr so aus (C / C ++ - Code voraus):
Es hat wahrscheinlich mehr Kollisionen als gewünscht, ist jedoch nicht für die Verwendung als kryptografische Hash-Funktion vorgesehen. Sie können verschiedene Multiplikatoren ausprobieren (dh die 37 in eine andere Primzahl ändern), wenn Sie zu viele Kollisionen erhalten. Eines der interessanten Merkmale dieses Snippets ist, dass Dest, wenn Src kürzer als Dest ist, die Eingabezeichenfolge unverändert erhält (0 * 37 + Wert = Wert). Wenn Sie am Ende des Prozesses etwas "Lesbares" wünschen, passt Normalize die transformierten Bytes auf Kosten zunehmender Kollisionen an.
Quelle:
https://github.com/cubiclesoft/cross-platform-cpp/blob/master/sync/sync_util.cpp
quelle
DestSize
mehr als 4 (32 Bit) , wenn der Hash selbst so beschissen ist? Wenn Sie die Kollisionsbeständigkeit einer Ausgabe wünschen, die größer als ein int ist, würden Sie SHA verwenden.