Super, vielen Dank für die sehr detaillierte Beschreibung
das hat mir ein ganzes Stück weitergeholfen. Ich glaube, langsam verstehe ich das mit dem Binären System dadrin und mit der Bit-Byte-Umrechnung. Irgendwo muss aber trotzdem noch ein Fehler sein...
Ich poste einfach mal den gesamten Code, wie er aktuell aussieht.
Dabei entspricht Int64ToBinLength fast deiner UInt64ToLELength-Funktion.
Die aktuellen Fehlersymptome:
Der erste Block des hashs lautet immer "$77777777".
Bei der 2. Verschlüsselung - und das erstaunt mich sehr - verändern sich der 2. und 3. Block. Der Hash ist folglich auch falsch
Delphi-Quellcode:
function TMD5.Crypt(text: string):string;
var
r: array[0..63] of longword;
k: array[0..63] of longword;
i, x, y: longword;
a, b, c, d: longword;
h0, h1, h2, h3: longword;
textlength: int64;
block: string;
w: array[0..15] of longword;
f, g: longword;
temp: longword;
begin
r[0] := 7;
r[1] := 12;
r[2] := 17;
r[3] := 22;
r[4] := 7;
r[5] := 12;
r[6] := 17;
r[7] := 22;
r[8] := 7;
r[9] := 12;
r[10] := 17;
r[11] := 22;
r[12] := 7;
r[13] := 12;
r[14] := 17;
r[15] := 22;
r[16] := 5;
r[17] := 9;
r[18] := 14;
r[19] := 20;
r[20] := 5;
r[21] := 9;
r[22] := 14;
r[23] := 20;
r[24] := 5;
r[25] := 9;
r[26] := 14;
r[27] := 20;
r[28] := 5;
r[29] := 9;
r[30] := 14;
r[31] := 20;
r[32] := 4;
r[33] := 11;
r[34] := 16;
r[35] := 23;
r[36] := 4;
r[37] := 11;
r[38] := 16;
r[39] := 23;
r[40] := 4;
r[41] := 11;
r[42] := 16;
r[43] := 23;
r[44] := 4;
r[45] := 11;
r[46] := 16;
r[47] := 23;
r[48] := 6;
r[49] := 10;
r[50] := 15;
r[51] := 21;
r[52] := 6;
r[53] := 10;
r[54] := 15;
r[55] := 21;
r[56] := 6;
r[57] := 10;
r[58] := 15;
r[59] := 21;
r[60] := 6;
r[61] := 10;
r[62] := 15;
r[63] := 21;
for i := 0 to 63 do
begin
k[i] := floor(abs(sin(i + 1) * power(2, 32)));
end;
h0 := $67452301;
h1 := $EFCDAB89;
h2 := $98BADCFE;
h3 := $10325476;
textlength := length(text) * 8;
text := text + #$80;
while ((length(text) * 8) mod 512) <> 448 do
text := text + #$00;
text := text + Int64ToBinLength(textlength);
for x := 1 to (length(text) * 8) div 512 do
begin
block := copy(text, (512 div 8) * x, 512 div 8);
for i := 0 to 15 do
move(block[i * 32 + 1], w, 32);
a := h0;
b := h1;
c := h2;
d := h3;
for i := 0 to 63 do
begin
if (0 <= i) and (i <= 15) then
begin
f := (b and c) or ((not b) and d);
g := i;
end
else if (16 <= i) and (i <= 31) then
begin
f := (b and d) or (c and (not d));
g := (5*i + 1) mod 16;
end
else if (32 <= i) and (i <= 47) then
begin
f := b xor c xor d;
g := (3*i + 5) mod 16;
end
else if (48 <= i) and (i <= 63) then
begin
f := c xor (b or (not d));
g := (7*i) mod 16;
end;
temp := d;
c := b;
b := ((a + f + k[i] + w[g]) shl (r[i])) or ((a + f + k[i] + w[g]) shr (32 - (r[i]))) + b;
a := temp;
end;
h0 := h0 + a;
h1 := h1 + b;
h2 := h2 + c;
h3 := h3 + d;
end;
Result := Format('$%.2x%.2x%.2x%.2x %.2x%.2x%.2x%.2x %.2x%.2x%.2x%.2x %.2x%.2x%.2x%.2x',
[h0 shr 0 and $ff, h0 shr 8 and $ff, h0 shr 16 and $ff, h0 shr 24 and $ff,
h1 shr 0 and $ff, h1 shr 8 and $ff, h1 shr 16 and $ff, h1 shr 24 and $ff,
h2 shr 0 and $ff, h2 shr 8 and $ff, h2 shr 16 and $ff, h2 shr 24 and $ff,
h3 shr 0 and $ff, h3 shr 8 and $ff, h3 shr 16 and $ff, h3 shr 24 and $ff]);
end;
Am meisten verwirrt mich, dass bei der 2. Verschlüsselung ein anderer Hash herauskommt. Eigentlich müsste ja eine komplett neue Runde erzeugt werden, da kanns doch nicht sein, dass etwas anderes herauskommt. Zumal ab dem 2. Versuch alle gleich sind...