program Prog;
uses Classes, SysUtils;
function leftrotate(x, c: Cardinal): Cardinal;
begin
leftrotate := (x shl c) or (x shr (32-c));
end;
const s: array[0..63] of Cardinal = (
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 );
K: array[0..63] of Cardinal = (
$d76aa478, $e8c7b756, $242070db, $c1bdceee,
$f57c0faf, $4787c62a, $a8304613, $fd469501,
$698098d8, $8b44f7af, $ffff5bb1, $895cd7be,
$6b901122, $fd987193, $a679438e, $49b40821,
$f61e2562, $c040b340, $265e5a51, $e9b6c7aa,
$d62f105d, $02441453, $d8a1e681, $e7d3fbc8,
$21e1cde6, $c33707d6, $f4d50d87, $455a14ed,
$a9e3e905, $fcefa3f8, $676f02d9, $8d2a4c8a,
$fffa3942, $8771f681, $6d9d6122, $fde5380c,
$a4beea44, $4bdecfa9, $f6bb4b60, $bebfbc70,
$289b7ec6, $eaa127fa, $d4ef3085, $04881d05,
$d9d4d039, $e6db99e5, $1fa27cf8, $c4ac5665,
$f4292244, $432aff97, $ab9423a7, $fc93a039,
$655b59c3, $8f0ccc92, $ffeff47d, $85845dd1,
$6fa87e4f, $fe2ce6e0, $a3014314, $4e0811a1,
$f7537e82, $bd3af235, $2ad7d2bb, $eb86d391 );
var a0,b0,c0,d0, a,b,c,d, f,g,dTemp: Cardinal;
Len: Integer;
Msg: array[0..63] of Char;
M: array[0..15] of Cardinal absolute Msg; //break chunk into sixteen 32-bit words M[j]
Str: String;
i: Integer;
ff: TFileStream;
wait: Char;
begin
a0 := $67452301;
b0 := $efcdab89;
c0 := $98badcfe;
d0 := $10325476;
Str := 'hello world';
Len := Length(Str);
FillChar(Msg, 64, 0);
for i:=1 to Len do Msg[i-1] := Str[i];
//append "1" bit to message
Msg[Len] := chr(128);
//append original length in bits mod (2 pow 64) to message
Msg[63-7] := chr(8*Len); //Update thanks to @MBo
//Process each 512-bit chunk of message- 1 only have 1 chunk
//TEST dump
// ff := TFileStream.create('test.txt', fmCreate);
// ff.write(msg, 64);
// ff.free;
//Initialize hash value for this chunk:
A := a0;
B := b0;
C := c0;
D := d0;
//Main loop:
for i := 0 to 63 do begin
if (i>=0) and (i<=15) then begin
F := (B and C) or ((not B) and D);
g := i;
end
else if (i>=16) and (i<=31) then begin
F := (D and B) or ((not D) and C);
g := (5*i + 1) mod 16;
end
else if (i>=32) and (i<=47) then begin
F := B xor C xor D;
g := (3*i + 5) mod 16;
end
else if (i>=48) and (i<=63) then begin
F := C xor (B or (not D));
g := (7*i) mod 16;
end;
dTemp := D;
D := C;
C := B;
B := B + leftrotate((A + F + K[i] + M[g]), s[i]);
A := dTemp;
end;
//Add this chunk's hash to result so far:
a0 := a0 + A;
b0 := b0 + B;
c0 := c0 + C;
d0 := d0 + D;
//This should give 5EB63BBBE01EEED093CB22BB8F5ACDC3
Writeln( IntToHex(a0,8) + IntToHex(b0,8) + IntToHex(c0,8) +IntToHex(d0,8) );
Readln(wait);
end.
cHJvZ3JhbSBQcm9nOwoKdXNlcyBDbGFzc2VzLCBTeXNVdGlsczsKCmZ1bmN0aW9uIGxlZnRyb3RhdGUoeCwgYzogQ2FyZGluYWwpOiBDYXJkaW5hbDsKYmVnaW4KICBsZWZ0cm90YXRlIDo9ICh4IHNobCBjKSBvciAoeCBzaHIgKDMyLWMpKTsKZW5kOwoKY29uc3QgczogYXJyYXlbMC4uNjNdIG9mIENhcmRpbmFsID0gKAogICAgNywgMTIsIDE3LCAyMiwgIDcsIDEyLCAxNywgMjIsICA3LCAxMiwgMTcsIDIyLCAgNywgMTIsIDE3LCAyMiwKICAgIDUsICA5LCAxNCwgMjAsICA1LCAgOSwgMTQsIDIwLCAgNSwgIDksIDE0LCAyMCwgIDUsICA5LCAxNCwgMjAsCiAgICA0LCAxMSwgMTYsIDIzLCAgNCwgMTEsIDE2LCAyMywgIDQsIDExLCAxNiwgMjMsICA0LCAxMSwgMTYsIDIzLAogICAgNiwgMTAsIDE1LCAyMSwgIDYsIDEwLCAxNSwgMjEsICA2LCAxMCwgMTUsIDIxLCAgNiwgMTAsIDE1LCAyMSApOwpLOiBhcnJheVswLi42M10gb2YgQ2FyZGluYWwgPSAoCiAgICAkZDc2YWE0NzgsICRlOGM3Yjc1NiwgJDI0MjA3MGRiLCAkYzFiZGNlZWUsCiAgICAkZjU3YzBmYWYsICQ0Nzg3YzYyYSwgJGE4MzA0NjEzLCAkZmQ0Njk1MDEsCiAgICAkNjk4MDk4ZDgsICQ4YjQ0ZjdhZiwgJGZmZmY1YmIxLCAkODk1Y2Q3YmUsCiAgICAkNmI5MDExMjIsICRmZDk4NzE5MywgJGE2Nzk0MzhlLCAkNDliNDA4MjEsCiAgICAkZjYxZTI1NjIsICRjMDQwYjM0MCwgJDI2NWU1YTUxLCAkZTliNmM3YWEsCiAgICAkZDYyZjEwNWQsICQwMjQ0MTQ1MywgJGQ4YTFlNjgxLCAkZTdkM2ZiYzgsCiAgICAkMjFlMWNkZTYsICRjMzM3MDdkNiwgJGY0ZDUwZDg3LCAkNDU1YTE0ZWQsCiAgICAkYTllM2U5MDUsICRmY2VmYTNmOCwgJDY3NmYwMmQ5LCAkOGQyYTRjOGEsCiAgICAkZmZmYTM5NDIsICQ4NzcxZjY4MSwgJDZkOWQ2MTIyLCAkZmRlNTM4MGMsCiAgICAkYTRiZWVhNDQsICQ0YmRlY2ZhOSwgJGY2YmI0YjYwLCAkYmViZmJjNzAsCiAgICAkMjg5YjdlYzYsICRlYWExMjdmYSwgJGQ0ZWYzMDg1LCAkMDQ4ODFkMDUsCiAgICAkZDlkNGQwMzksICRlNmRiOTllNSwgJDFmYTI3Y2Y4LCAkYzRhYzU2NjUsCiAgICAkZjQyOTIyNDQsICQ0MzJhZmY5NywgJGFiOTQyM2E3LCAkZmM5M2EwMzksCiAgICAkNjU1YjU5YzMsICQ4ZjBjY2M5MiwgJGZmZWZmNDdkLCAkODU4NDVkZDEsCiAgICAkNmZhODdlNGYsICRmZTJjZTZlMCwgJGEzMDE0MzE0LCAkNGUwODExYTEsCiAgICAkZjc1MzdlODIsICRiZDNhZjIzNSwgJDJhZDdkMmJiLCAkZWI4NmQzOTEgKTsKCnZhciBhMCxiMCxjMCxkMCwgYSxiLGMsZCwgZixnLGRUZW1wOiBDYXJkaW5hbDsKICAgTGVuOiBJbnRlZ2VyOwogICBNc2c6IGFycmF5WzAuLjYzXSBvZiBDaGFyOwogICBNOiBhcnJheVswLi4xNV0gb2YgQ2FyZGluYWwgYWJzb2x1dGUgTXNnOyAvL2JyZWFrIGNodW5rIGludG8gc2l4dGVlbiAzMi1iaXQgd29yZHMgTVtqXQogICBTdHI6IFN0cmluZzsKICAgaTogSW50ZWdlcjsKICAgZmY6IFRGaWxlU3RyZWFtOwogICB3YWl0OiBDaGFyOwpiZWdpbgogIGEwIDo9ICQ2NzQ1MjMwMTsKICBiMCA6PSAkZWZjZGFiODk7CiAgYzAgOj0gJDk4YmFkY2ZlOwogIGQwIDo9ICQxMDMyNTQ3NjsKCiAgU3RyIDo9ICdoZWxsbyB3b3JsZCc7CiAgTGVuIDo9IExlbmd0aChTdHIpOwoKICBGaWxsQ2hhcihNc2csIDY0LCAwKTsKCiAgZm9yIGk6PTEgdG8gTGVuIGRvIE1zZ1tpLTFdIDo9IFN0cltpXTsKCi8vYXBwZW5kICIxIiBiaXQgdG8gbWVzc2FnZQogIE1zZ1tMZW5dIDo9IGNocigxMjgpOwoKLy9hcHBlbmQgb3JpZ2luYWwgbGVuZ3RoIGluIGJpdHMgbW9kICgyIHBvdyA2NCkgdG8gbWVzc2FnZQogIE1zZ1s2My03XSA6PSBjaHIoOCpMZW4pOyAgLy9VcGRhdGUgdGhhbmtzIHRvIEBNQm8KCi8vUHJvY2VzcyBlYWNoIDUxMi1iaXQgY2h1bmsgb2YgbWVzc2FnZS0gMSBvbmx5IGhhdmUgMSBjaHVuawoKLy9URVNUIGR1bXAKLy8gIGZmIDo9IFRGaWxlU3RyZWFtLmNyZWF0ZSgndGVzdC50eHQnLCBmbUNyZWF0ZSk7Ci8vICBmZi53cml0ZShtc2csIDY0KTsKLy8gIGZmLmZyZWU7CgovL0luaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuazoKICAgIEEgOj0gYTA7CiAgICBCIDo9IGIwOwogICAgQyA6PSBjMDsKICAgIEQgOj0gZDA7CgovL01haW4gbG9vcDoKICAgIGZvciBpIDo9IDAgdG8gNjMgZG8gYmVnaW4KCiAgICAgICAgaWYgKGk+PTApIGFuZCAoaTw9MTUpIHRoZW4gYmVnaW4KICAgICAgICAgICAgRiA6PSAoQiBhbmQgQykgb3IgKChub3QgQikgYW5kIEQpOwogICAgICAgICAgICBnIDo9IGk7CiAgICAgICAgZW5kCiAgICAgICAgZWxzZSBpZiAoaT49MTYpIGFuZCAoaTw9MzEpIHRoZW4gYmVnaW4KICAgICAgICAgICAgRiA6PSAoRCBhbmQgQikgb3IgKChub3QgRCkgYW5kIEMpOwogICAgICAgICAgICBnIDo9ICg1KmkgKyAxKSBtb2QgMTY7CiAgICAgICAgZW5kCiAgICAgICAgZWxzZSBpZiAoaT49MzIpIGFuZCAoaTw9NDcpIHRoZW4gYmVnaW4KICAgICAgICAgICAgRiA6PSBCIHhvciBDIHhvciBEOwogICAgICAgICAgICBnIDo9ICgzKmkgKyA1KSBtb2QgMTY7CiAgICAgICAgZW5kCiAgICAgICAgZWxzZSBpZiAoaT49NDgpIGFuZCAoaTw9NjMpIHRoZW4gYmVnaW4KICAgICAgICAgICAgRiA6PSBDIHhvciAoQiBvciAobm90IEQpKTsKICAgICAgICAgICAgZyA6PSAoNyppKSBtb2QgMTY7CiAgICAgICAgZW5kOwoKICAgICAgICBkVGVtcCA6PSBEOwogICAgICAgIEQgOj0gQzsKICAgICAgICBDIDo9IEI7CiAgICAgICAgQiA6PSBCICsgbGVmdHJvdGF0ZSgoQSArIEYgKyBLW2ldICsgTVtnXSksIHNbaV0pOwogICAgICAgIEEgOj0gZFRlbXA7CiAgICBlbmQ7CgovL0FkZCB0aGlzIGNodW5rJ3MgaGFzaCB0byByZXN1bHQgc28gZmFyOgogIGEwIDo9IGEwICsgQTsKICBiMCA6PSBiMCArIEI7CiAgYzAgOj0gYzAgKyBDOwogIGQwIDo9IGQwICsgRDsKCiAgLy9UaGlzIHNob3VsZCBnaXZlIDVFQjYzQkJCRTAxRUVFRDA5M0NCMjJCQjhGNUFDREMzCiAgV3JpdGVsbiggSW50VG9IZXgoYTAsOCkgKyBJbnRUb0hleChiMCw4KSArIEludFRvSGV4KGMwLDgpICArSW50VG9IZXgoZDAsOCkgKTsKCiAgUmVhZGxuKHdhaXQpOwplbmQu