if (lX4 or lY4) <> 0 then
begin
if (lResult and $40000000) <>0 then
begin result := (lResult xor $C0000000 xor lX8 xor lY8); end
else
begin result := (lResult xor $40000000 xor lX8 xor lY8); end
end
else
begin result := (lResult xor lX8 xor lY8); end
end;
function F(x,y,z:integer):integer; begin result := (x and y) or (( not x) and z); end;
function G(x,y,z:integer):integer; begin result := (x and z) or (y and ( not z)); end;
function H(x,y,z:integer):integer; begin result := (x xor y xor z); end;
function I(x,y,z:integer):integer; begin result := (y xor (x or ( not z))); end;
function FF(a,b,c,d,x,s,ac:integer):integer;
begin
a := AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
result := AddUnsigned(RotateLeft(a, s), b);
end;
function GG(a,b,c,d,x,s,ac:integer):integer;
begin
a := AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
result := AddUnsigned(RotateLeft(a, s), b);
end;
function HH(a,b,c,d,x,s,ac:integer):integer;
begin
a := AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
result := AddUnsigned(RotateLeft(a, s), b);
end;
function II(a,b,c,d,x,s,ac:integer):integer;
begin
a := AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
result := AddUnsigned(RotateLeft(a, s), b);
end;
type IntArray = array of integer;
function ConvertToWordArray(sMessage:WideString):IntArray;
var lWordCount:integer;
var lMessageLength:integer;
var lNumberOfWords_temp1:integer;
var lNumberOfWords_temp2:integer;
var lNumberOfWords:integer;
var lWordArray:IntArray;
var lBytePosition:integer;
var lByteCount:integer;
begin
lMessageLength := length(sMessage);
lNumberOfWords_temp1:=lMessageLength + 8;
lNumberOfWords_temp2:=(lNumberOfWords_temp1-(lNumberOfWords_temp1 mod 64)) div 64;
lNumberOfWords := (lNumberOfWords_temp2+1)*16;
SetLength(lWordArray,lNumberOfWords);
lBytePosition := 0;
lByteCount := 0;
while ( lByteCount < lMessageLength ) do
begin
lWordCount := (lByteCount-(lByteCount mod 4)) div 4;
lBytePosition := (lByteCount mod 4)*8;
lWordArray[lWordCount] := (lWordArray[lWordCount] or (ord(sMessage[lByteCount+1]) shl lBytePosition));
inc(lByteCount);
end;
lWordCount := (lByteCount-(lByteCount mod 4)) div 4;
lBytePosition := (lByteCount mod 4)*8;
lWordArray[lWordCount] := lWordArray[lWordCount] or ($80 shl lBytePosition);
lWordArray[lNumberOfWords-2] := lMessageLength shl 3;
lWordArray[lNumberOfWords-1] := lMessageLength shr 29;
result := lWordArray;
end;
function WordToHex(lValue:integer):WideString;
var WordToHexValue,WordToHexValue_temp:WideString;
lByte,lCount:integer;
begin
Result := '';
for lCount := 0 to 3 do
begin
lByte := (lValue shr (lCount*8)) and 255;
result := result + IntToHex(lByte,2);
end;
end;
var x:IntArray;
k,AA,BB,CC,DD,a,b,c,d:integer;
const S11:integer=7;
S12:integer=12;
S13:integer=17;
S14:integer=22;
function RotateLeft(lValue, iShiftBits:integer):integer;
begin
result := (lValue shl iShiftBits) or (lValue shr (32-iShiftBits));
end;
function AddUnsigned(lX,lY:integer):integer;
var
lX4,lY4,lX8,lY8,lResult:integer;
begin
lX8 := (lX and $80000000);
lY8 := (lY and $80000000);
lX4 := (lX and $40000000);
lY4 := (lY and $40000000);
lResult := (lX and $3FFFFFFF)+(lY and $3FFFFFFF);
if (lX4 and lY4) <> 0 then begin result := (lResult xor $80000000 xor lX8 xor lY8); Exit; end;
// Encode Count bytes at Source into (Count / 4) DWORDs at Target
procedure Encode(Source, Target: pointer; Count: longword);
var
S: PByte;
T: PDWORD;
I: longword;
begin
S := Source;
T := Target;
for I := 1 to Count div 4 do begin
T^ := S^;
inc(S);
T^ := T^ or (S^ shl 8);
inc(S);
T^ := T^ or (S^ shl 16);
inc(S);
T^ := T^ or (S^ shl 24);
inc(S);
inc(T);
end;
end;
// Decode Count DWORDs at Source into (Count * 4) Bytes at Target
procedure Decode(Source, Target: pointer; Count: longword);
var
S: PDWORD;
T: PByte;
I: longword;
begin
S := Source;
T := Target;
for I := 1 to Count do begin
T^ := S^ and $ff;
inc(T);
T^ := (S^ shr 8) and $ff;
inc(T);
T^ := (S^ shr 16) and $ff;
inc(T);
T^ := (S^ shr 24) and $ff;
inc(T);
inc(S);
end;
end;