Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.167 Beiträge
 
Delphi 12 Athens
 
#14

Re: MD5 Länge einfügen als 64 Bit?

  Alt 1. Mär 2009, 18:10
Zitat von fortuneNext:
Könnte es also an der Vorbereitung liegen?
Delphi-Quellcode:
  textlength := length(text) * 8;
  textlengthbin := IntToBin(textlength);
  text := text + '1';
  while ((length(text) * 8) mod 512) <> 448 do
    text := text + '0';
  while (length(textlengthbin) * 8) mod 512 <> 64 do
    textlengthbin := '0' + textlengthbin;
  text := text + textlengthbin;
jupp, in dem Beispiel ist ja von 0 und 1 als Bit die Rede, wenn man das ganze jetzt auf ganze Bytes hochrechnet, dann muß man hier indireckt einen Schritt vorziehen.

eine 1 anhängen und danach gleich noch 7 mal eine 0 ergibt binär ein Byte mit b10000000, was hexadezimal der $80 entspricht, also dem Char #128 bzw. #$80.
und danach kann man dann weiterhin soviele 0 in 8-er-Grüppchen anhängen, bis die 448 erreicht ist.
also b00000000 = $00 = #0

Ord('0') und Ord('1') entsprechen aber nicht der binären 0 und 1

'0' = #48 <> #$00
'1' = #49 <> #$80


Vielleicht liegt die Fehlerquelle auch woanders. Die Zuweisung von w ist mir auch sehr ins Auge gesprungen:
Pointer(w) := PAnsiChar(message); Diese Zeile verstehe ich leider nicht. Wie kommen denn da 32-Bit-Blöcke heraus?

Im Grunde hab ich mir da nur das kopieren gesparrt.
Wenn du dir die Definition von w (bei mir) ansiehst, wirst du die einzelnen 32-Bit-Blöcke erkennen.
Da w bei mir ein Pointer ist, konnte ich diesen einfach auf den Anfang des Strings legen, somit also seine 32-Bit-Blöcke geneu über die Daten des Strings legen.

OK, ich hätte w auch als "eigenständige" Variable definieren können und dann je 512 Bit (16 * 32 Bit = 64 Byte) vom String da reinkkopieren müssen.
(hab aber statt zu die Daten in w reinzukopieren nur das w über die Daten verschoben)

Zitat von fortuneNext:
Bei mir siehen die Blockunterteilungen so aus:
Delphi-Quellcode:
  for x := 1 to (length(text) * 8) div 512 do
  begin
    block := copy(text, x * (512 div 8) + 1, 512 div 8);
    for i := 0 to 15 do
      w[i] := StrToInt(copy(block, (i + 1) * (32 div 8), 32 div 8));

{...}
Hier hattest du noch einen Fehler.
du mußt den String binär ansehn, also die Bits direkt in w[i] kopieren und nicht umwandeln (StrToInt).
Delphi-Quellcode:
for x := 1 to (length(text) * 8) div 512 do
begin
  block := copy(text, x * (512 div 8) + 1, 512 div 8);
  for i := 0 to 15 do
    w[i] := LongWord(Ord(block[(i * (32 div 8)) + 1]))
        or (LongWord(Ord(block[(i * (32 div 8)) + 2])) shl 8)
        or (LongWord(Ord(block[(i * (32 div 8)) + 3])) shl 16)
        or (LongWord(Ord(block[(i * (32 div 8)) + 4])) shl 24);
man könnte jetzt auch einfach sich 4 Zeichen nehmen und diese direkt in einen LongWord casten
Delphi-Quellcode:
for x := 1 to (length(text) * 8) div 512 do
begin
  block := copy(text, 512 div 8, 512 div 8);
  for i := 0 to 15 do
    w[i] := PLongWord(@block[(i * (32 div 8)) + 1])^;
und du hattest vergessen das x in die Verarbeitung mit einzurechnen ... mit x * (512 div 8) + 1 wird auf den Anfang des aktuellen Blocks verwiesen.

Zitat von fortuneNext:
Für die Ausgabe habe ich vorläufig erstmal die oben stehende Lösung genutzt (danke auch nochmal dafür ), damit ich erstmal überhaupt einen Hash herausbekomme, um zu sehen, ob es der Richtige ist - ich werde mir aber auch noch einmal eine eigene Lösung erarbeiten
bin auch gespannt, was bei dir dann mal rauskommt ... schließlich gibt es ja mehrere Wege das ganze in Delphi umzusetzen.

Zitat von fortuneNext:
PS: Ganz am Rande... ich habe logische Operatoren vorher nicht sonderlich oft auf Integer angewendet - was AND und OR bewirken, ließ sich recht schnell erschließen, aber was bewirkt denn NOT, sodass aus einer 4 eine -5 wird?
AND, OR, NOT, XOR und SHL bzw. SHR verarbeiten ja erstmal direkt die einzelnen Bits der einzelnen Werte.
NOT kehrt dabei dir Bits einfach um. (aus b1101000 wird also b0010111)

Warum da aus einer 4 eine -5 wird, liegt an der Interpretation dieser Bits.
Bei einem Integer werden die Bits nach dem Zweierkomplement ausgewertet.


PS: die x-Schleife von dir ist eigentlich optimaler
for x := 1 to (length(text) * 8) div 512 do ich hatte die Verarbeitung immer auf den Stringanfang gelegt und nach jedem Durchgang den eben verarbeiteten Stringteil rausgelöscht.
wenn ich da (ähnlich wie bei dir) die Verarbeitung verschieben würde und die "langsame" Stringverarbeitung (das Löschen) stattdessen wegließe, dann wäre es natürlich schneller ... aber da ich in Wiki's Code keine Schleifenvariable (wie dein x) vorfand, hatte ich es so gelöst (ohne Variable und dafür mit Löschen).


[add]
Hab mein Beispiel mal so umgestllt, daß jetzt nicht mehr gelöscht wird und stattdessen eine Variable wie dein x (hab'se i2 genannt) verwendet wird.

Außerdem gibt's eine Version wo weiterhin w als Pointer-Array über die Daten geschoben wird
und dann noch 'ne Version, wo w als eigentsändiges Array existiert und die Daten da reinkopiet werden.
Angehängte Dateien
Dateityp: zip projects_956.zip (6,8 KB, 7x aufgerufen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat