MD5/Implementation: Difference between revisions

Added Delphi example
m (→‎{{header|REXX}}: added whitespace.)
(Added Delphi example)
Line 1,339:
 
As you see this asm is much faster than the D code compiled by dmd, but the D code compiled by ldc2 is a little faster still.
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Classes}}
{{Trans|Go}}
<lang Delphi>
program MD5Implementation;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Classes;
 
type
TTestCase = record
hashCode: string;
_: string;
end;
 
var
testCases: array[0..6] of TTestCase = ((
hashCode: 'D41D8CD98F00B204E9800998ECF8427E';
_: ''
), (
hashCode: '0CC175B9C0F1B6A831C399E269772661';
_: 'a'
), (
hashCode: '900150983CD24FB0D6963F7D28E17F72';
_: 'abc'
), (
hashCode: 'F96B697D7CB7938D525A2F31AAF161D0';
_: 'message digest'
), (
hashCode: 'C3FCD3D76192E4007DFB496CCA67E13B';
_: 'abcdefghijklmnopqrstuvwxyz'
), (
hashCode: 'D174AB98D277D9F5A5611C2C9F419D9F';
_: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
), (
hashCode: '57EDF4A22BE3C955AC49DA2E2107B67A';
_: '12345678901234567890123456789' + '012345678901234567890123456789012345678901234567890'
));
shift: array of UInt32 = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21];
table: array[0..63] of UInt32;
 
procedure Init();
var
i: integer;
 
function fAbs(x: Extended): Extended;
begin
if x < 0 then
exit(-x);
exit(x);
end;
 
begin
for i := 0 to High(table) do
table[i] := Trunc((UInt64(1) shl 32) * fAbs(Sin(i + 1.0)));
end;
 
function Md5(s: string): TBytes;
const
BUFFER_SIZE = 16;
var
binary: TBytesStream;
buffer: Tarray<UInt32>;
messageLenBits: UInt64;
i, j, bufferIndex, count: integer;
byte_data: byte;
string_data: ansistring;
k, k1: Tarray<UInt32>;
f, rnd, sa: UInt32;
tmp: UInt64;
begin
k := [$67452301, $EFCDAB89, $98BADCFE, $10325476];
 
binary := TBytesStream.Create();
 
if not s.IsEmpty then
begin
string_data := Utf8ToAnsi(s);
binary.Write(Tbytes(string_data), length(string_data));
end;
 
byte_data := $80;
binary.Write(byte_data, 1);
 
messageLenBits := UInt64(s.Length * 8);
count := s.Length + 1;
 
while (count mod 64) <> 56 do
begin
byte_data := $00;
binary.Write(byte_data, 1);
inc(count);
end;
 
binary.Write(messageLenBits, sizeof(messageLenBits));
 
SetLength(buffer, BUFFER_SIZE);
SetLength(k1, length(k));
 
binary.Seek(0, soFromBeginning);
 
while binary.Read(buffer[0], BUFFER_SIZE * 4) > 0 do
begin
for i := 0 to 3 do
k1[i] := k[i];
 
for i := 0 to 63 do
begin
f := 0;
bufferIndex := i;
rnd := i shr 4;
case rnd of
0:
f := (k1[1] and k1[2]) or (not k1[1] and k1[3]);
1:
begin
f := (k1[1] and k1[3]) or (k1[2] and not k1[3]);
bufferIndex := (bufferIndex * 5 + 1) and $0F
end;
2:
begin
f := k1[1] xor k1[2] xor k1[3];
bufferIndex := (bufferIndex * 3 + 5) and $0F;
end;
3:
begin
f := k1[2] xor (k1[1] or not k1[3]);
bufferIndex := (bufferIndex * 7) and $0F;
end;
end;
 
sa := shift[(rnd shl 2) or (i and 3)];
 
k1[0] := k1[0] + f + buffer[bufferIndex] + table[i];
 
tmp := k1[0];
 
k1[0] := k1[3];
k1[3] := k1[2];
k1[2] := k1[1];
 
k1[1] := ((tmp shl sa) or (tmp shr (32 - sa))) + k1[1];
end;
 
for i := 0 to 3 do
k[i] := k[i] + k1[i];
end;
 
SetLength(result, BUFFER_SIZE);
 
binary.Clear;
for i := 0 to 3 do
binary.Write(k[i], 4);
 
binary.Seek(0, soBeginning);
 
binary.Read(Result, BUFFER_SIZE);
 
binary.Free;
end;
 
function BytesToString(b: TBytes): string;
var
v: byte;
begin
Result := '';
for v in b do
Result := Result + v.ToHexString(2);
end;
 
var
tc: TTestCase;
 
begin
Init;
 
for tc in testCases do
Writeln(Format('%s'#10'%s'#10, [tc.hashCode, BytesToString(md5(tc._))]));
Readln;
end.</lang>
 
=={{header|F#}}==
478

edits