MD5/Implementation: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: added whitespace.) |
MaiconSoft (talk | contribs) (Added Delphi example) |
||
Line 1,339: | 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. |
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#}}== |
=={{header|F#}}== |