| Cryptography & Encryption Ver- und Entschlüsselung, Algorithmen, Kryptoanalyse ? Kryptographie in der Praxis. Blowfish, Triple-DES, XOR u.a. |
Diskussion: String zum hash annähern im Forum Cryptography & Encryption, in der Kategorie Security Area; Anzeige Hallo Leute ich suche einen String der diesen Hash ergibt: "1307907743251498231" = 19 bit Den Quellcode für den hash ...
![]() |
| | #1 (permalink) |
| Registriert seit: 26.04.11 ![]() Likes: 0 | Anzeige Hallo Leute ich suche einen String der diesen Hash ergibt: "1307907743251498231" = 19 bit Den Quellcode für den hash hab ich angefügt. Code: def calculate_hash(input):
h = 0;
lenge = len(input);
for element in xrange(lenge):
h = 31 * h + ord(input[element]);
return h; Max hash: 1307908077598578441 'Max element: ', ('0', 'h', 'p', 'p', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ') Amar seed: 1307907743251498231 Min hash: 1307907695173242296 'Min element: ', ('0', 'h', 'p', 'p', '_', '_', '_', '_', '_', '_', '_', '_') Was meint Ihr, wie komme ich auf den String? |
| | |
| | #2 (permalink) |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | Es lässt sich auch kürzer schreiben Code: def calculate_hash(input):
h = 0;
for element in input:
h = h * 31 + ord(element)
return h Code: def calc_hash(input): return reduce(lambda x, y: x * 31 + ord(y), input,0) D.h: Es gibt insgesamt 256 mögliche Werte pro Zeichen. Da das (Hash - Zeichen) ein Vielfaches von 31 ergeben muss, lässt sich das ziemlich einschränken. Hash modulo 31 ergibt einen "Kandidaten" für eine Lösung cand = hash % 31 mögl. Zeichen = cand +31 * x mit x = 0 .. 9. Dies und die Tatsache, dass der Hashwert nicht "abgeschnitten" wird, schränken den Suchraum ziemlich ein. Es lässt sich zumindest ein Bruteforcer schreiben, der alle Lösungen in annehmbarer Zeit findet - vor allem wenn man davon ausgeht, dass die Zeichen "printable" sein sollten Code: >>> def clever_bf(x, solution, printable): ... if x < 0: ... return ... elif x == 0: ... res.append(solution) ... return ... for i in xrange(10): ... candidate = (x % 31) + 31 * i ... if candidate < 256 and (chr(candidate) in printable): ... clever_bf((x-candidate) / 31, chr(candidate) + solution, printable) ... >>> res = [] >>> my_chars = string.uppercase + string.lowercase + string.digits >>> clever_bf(1307907743251498231, "", my_chars) Ergebnisse: Code: >>> len(res) 29160 >>> res[0] '1K43C9FL9869' >>> res[2] '1JS3C9FL9869' >>> calculate_hash(res[0]) 1307907743251498231L >>> calculate_hash(res[10]) 1307907743251498231L >>> res=[] >>> clever_bf(1307907743251498231, "", string.uppercase) >>> len(res) 0 >>> clever_bf(1307907743251498231, "", string.lowercase) >>> len(res) 0 >>> clever_bf(1307907743251498231, "", string.lowercase+string.digits) >>> len(res) 64 >>> res[0] '0j42b8dk9869' >>> clever_bf(1307907743251498231, "", string.printable) >>> len(res) 332488 >>> res[0] '0j42b8dk9869' >>> res[1000] '3\r42`wG-9869'
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. Geändert von CDW (13.12.11 um 22:18 Uhr) Grund: korrigiert |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) | |
| Themenstarter Registriert seit: 26.04.11 ![]() Likes: 0 | Sehr beindruckend, ich hätte nicht gedacht das jemand so schnell auf eine Lösung kommt. Die Annäherung hatte ja gezeigt das es sehr wahrscheinlich ein String mit 12 Zeichen sein muss. Ehrlich gesagt bin ich noch dabei den Code zu verdauen wie kommst du auf Zitat:
Wenn ich einen beliebigen String nehme mit a0**exp11+a**exp10 usw komme ich auch auf das Ergebnis, nur warum ist dein x [0:9], ich hätte ein x von [0:12] gewählt. Da aber deine Funktion auch mit einem x=4 richtige Ergebnisse auspuckt bin ich nun verwirrt. Vielen Dank nochmals der Code ist sehr Lehrreich für mich. Gruß polle | |
| | |
| | #4 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | Zitat:
Ich versuche nicht als Polynom zu betrachten, sondern den Hash "zurückzurechnen". Wir haben ja sowas: Code: h=0 for char in input: h = 31 * h + char wird h * 31 + char => 'endgültiger Hash' gebildet. bzw: h' * 31 + val = h | mit h' = Vorgänger von h und h ist bekannt Dabei: h' * 31 + val = h <=> h - val = h' * 31 <=> (h - val) / 31 = h' <=> h/31 - val/31 = h' wäre val jetzt eine "normale" natürliche Zahl, hätten wir ein Problem. Allerdings wissen wir, dass val ein ASCII Zeichen bzw. Byte ist mit einem Wertebereich [0..255] Und wir wissen, dass alle h, h', h'' .. 0 ganzzahlig sind d.h h MOD 31 = "Überschuss/Rest" r val kann also logisch betrachtet nur r, r+31, r+31*2, r+31*3 ... r+31*n mit r + 31*n < 256 sein (da es sonst nicht mehr in 1 Byte passen würde) (entspricht im vorherigen Post: cand + 31*x) Wenn r = 0 ist, so müssen wir im Worstcase n = höchstens 256/31 = 9 betrachten. Das sind die Kandidaten für ein mögliches Zeichen (insgesamt 10) also h' = h - (r + 31*n mit n [0..9]) r2 = h' MOD 31 h'' = h' - (r2 + 31 * n) ... 0 = h''''' - (r_len + 31 * n) Im Algo wird die BF-Funktion dann rekursiv für alle Kandidaten aufgerufen Code: clever_bf((x-candidate) / 31, chr(candidate) + solution, printable) Unser BF-Aufwand hängt zwar immer noch von der Länge ab, beträgt aber nicht 255**n bzw. 80**n sondern 10**n bzw. 4**n (Pi * Daumen abgeschätzt, da ich k.A mehr habe, wie ich hier die tatsächliche Verteilung der printable ASCIIs berücksichtigen sollte Wobei der BF Algo zum einen den kompletten Lösungsraum ausgibt und zum anderen ziemlich naiv läuft. Imho lässt der Hashalgo so viele Kollisionen zu, dass sich eine entsprechende Heuristik schreiben lassen sollte, die fast alles "zurückrechnet" und die verbliebenen paar Zeichen (entsprechen den ersten paar Zeichen der Eingabe) "bruteforced", so dass auch das erste Zeichen der Eingabe "printable" ist. Der Aufwand dürfte damit prinzipiell linear sein. Als erste Annäherung sollte allerdings auch ausreichen, mit dem BF aufzuhören, sobald 1 gültige Lösung gefunden wurde eine mögiche Version Edit/PS: der Java-Hash Algo (der hier scheinbar zugrunde liegt Eine Kollision sollte sich zwar immer noch recht Problemlos finden, allerdings ist es kein Crypto-Hashverfahren, sondern nur eins für eine ausreichend eindeutige Zuordnung String -> Zahl. Wird für Stringpools/Associative Arrays/HasMaps/Dicts usw. genutzt.
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Unbekannter String/Hash | Vafthrudnir | Cryptography & Encryption | 6 | 30.09.11 23:32 |
| Was für ein hash? | -Tux- | Cryptography & Encryption | 3 | 10.02.09 08:33 |
| [C/C++] MD5 Hash von String | Nimda05 | Code Kitchen | 9 | 31.05.07 22:24 |
| Was ist das für ein Hash ? | Cylence | Cryptography & Encryption | 3 | 10.05.07 21:31 |
| SAM Hash | master_tux | Windows | 2 | 19.03.06 20:43 |