unit uMD5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics;
type
MD5Count = array[..] of DWORD;
MD5State = array[..] of DWORD;
MD5Block = array[..] of DWORD;
MD5CBits = array[..] of Byte;
MD5Digest = array[..] of Byte;
MD5Buffer = array[..] of Byte;
MD5Context = record
State: MD5State;
Count: MD5Count;
Buffer: MD5Buffer;
end;
procedure MD5Init(var Context: MD5Context);
procedure MD5Update(var Context: MD5Context; Input: PAnsiChar; Length: longword);
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
function MD5File(N: string): MD5Digest;
function MD5Print(D: MD5Digest): AnsiString;
function MD5F(FileName: AnsiString): AnsiString;
function MD5S(Str: AnsiString): AnsiString;
function MD5FileText(filename: AnsiString): AnsiString;
var
PADDING: MD5Buffer = ($, $, $, $, $, $, $, $, $, $, $,
$, $, $, $, $, $, $, $, $, $, $, $, $, $, $,
$, $, $, $, $, $, $, $, $, $, $, $, $, $, $,
$, $, $, $, $, $, $, $, $, $, $, $, $, $, $,
$, $, $, $, $, $, $, $);
implementation
function F(x, y, z: DWORD): DWORD;
begin
Result := (x and y) or ((not x) and z);
end;
function G(x, y, z: DWORD): DWORD;
begin
Result := (x and z) or (y and (not z));
end;
function H(x, y, z: DWORD): DWORD;
begin
Result := x xor y xor z;
end;
function I(x, y, z: DWORD): DWORD;
var
I: TObject;
begin
Result := y xor (x or (not z));
end;
procedure rot(var x: DWORD; N: Byte);
begin
x := (x shl N) or (x shr ( - N));
end;
procedure FF(var a: DWORD; b, c, D, x: DWORD; s: Byte; ac: DWORD);
begin
inc(a, F(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
end;
procedure GG(var a: DWORD; b, c, D, x: DWORD; s: Byte; ac: DWORD);
begin
inc(a, G(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
end;
procedure HH(var a: DWORD; b, c, D, x: DWORD; s: Byte; ac: DWORD);
begin
inc(a, H(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
end;
procedure II(var a: DWORD; b, c, D, x: DWORD; s: Byte; ac: DWORD);
begin
inc(a, I(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
end;
procedure Encode(Source, Target: pointer; Count: longword);
var
s: PByte;
T: PDWORD;
I: longword;
begin
s := Source;
T := Target;
for I := to Count div do
begin
T^ := s^;
inc(s);
T^ := T^ or (s^ shl );
inc(s);
T^ := T^ or (s^ shl );
inc(s);
T^ := T^ or (s^ shl );
inc(s);
inc(T);
end;
end;
procedure Decode(Source, Target: pointer; Count: longword);
var
s: PDWORD;
T: PByte;
I: longword;
begin
s := Source;
T := Target;
for I := to Count do
begin
T^ := s^ and $FF;
inc(T);
T^ := (s^ shr ) and $FF;
inc(T);
T^ := (s^ shr ) and $FF;
inc(T);
T^ := (s^ shr ) and $FF;
inc(T);
inc(s);
end;
end;
procedure Transform(Buffer: pointer; var State: MD5State);
var
a, b, c, D: DWORD;
Block: MD5Block;
begin
Encode(Buffer, @Block, );
a := State[];
b := State[];
c := State[];
D := State[];
FF(a, b, c, D, Block[], , $D76AA478);
FF(D, a, b, c, Block[], , $E8C7B756);
FF(c, D, a, b, Block[], , $242070DB);
FF(b, c, D, a, Block[], , $C1BDCEEE);
FF(a, b, c, D, Block[], , $F57C0FAF);
FF(D, a, b, c, Block[], , $4787C62A);
FF(c, D, a, b, Block[], , $A8304613);
FF(b, c, D, a, Block[], , $FD469501);
FF(a, b, c, D, Block[], , $698098D8);
FF(D, a, b, c, Block[], , $8B44F7AF);
FF(c, D, a, b, Block[], , $FFFF5BB1);
FF(b, c, D, a, Block[], , $895CD7BE);
FF(a, b, c, D, Block[], , $6B901122);
FF(D, a, b, c, Block[], , $FD987193);
FF(c, D, a, b, Block[], , $A679438E);
FF(b, c, D, a, Block[], , $49B40821);
GG(a, b, c, D, Block[], , $F61E2562);
GG(D, a, b, c, Block[], , $C040B340);
GG(c, D, a, b, Block[], , $265E5A51);
GG(b, c, D, a, Block[], , $E9B6C7AA);
GG(a, b, c, D, Block[], , $D62F105D);
GG(D, a, b, c, Block[], , $);
GG(c, D, a, b, Block[], , $D8A1E681);
GG(b, c, D, a, Block[], , $E7D3FBC8);
GG(a, b, c, D, Block[], , $21E1CDE6);
GG(D, a, b, c, Block[], , $C33707D6);
GG(c, D, a, b, Block[], , $F4D50D87);
GG(b, c, D, a, Block[], , $455A14ED);
GG(a, b, c, D, Block[], , $A9E3E905);
GG(D, a, b, c, Block[], , $FCEFA3F8);
GG(c, D, a, b, Block[], , $676F02D9);
GG(b, c, D, a, Block[], , $8D2A4C8A);
HH(a, b, c, D, Block[], , $FFFA3942);
HH(D, a, b, c, Block[], , $8771F681);
HH(c, D, a, b, Block[], , $6D9D6122);
HH(b, c, D, a, Block[], , $FDE5380C);
HH(a, b, c, D, Block[], , $A4BEEA44);
HH(D, a, b, c, Block[], , $4BDECFA9);
HH(c, D, a, b, Block[], , $F6BB4B60);
HH(b, c, D, a, Block[], , $BEBFBC70);
HH(a, b, c, D, Block[], , $289B7EC6);
HH(D, a, b, c, Block[], , $EAA127FA);
HH(c, D, a, b, Block[], , $D4EF3085);
HH(b, c, D, a, Block[], , $4881D05);
HH(a, b, c, D, Block[], , $D9D4D039);
HH(D, a, b, c, Block[], , $E6DB99E5);
HH(c, D, a, b, Block[], , $1FA27CF8);
HH(b, c, D, a, Block[], , $C4AC5665);
II(a, b, c, D, Block[], , $F4292244);
II(D, a, b, c, Block[], , $432AFF97);
II(c, D, a, b, Block[], , $AB9423A7);
II(b, c, D, a, Block[], , $FC93A039);
II(a, b, c, D, Block[], , $655B59C3);
II(D, a, b, c, Block[], , $8F0CCC92);
II(c, D, a, b, Block[], , $FFEFF47D);
II(b, c, D, a, Block[], , $85845DD1);
II(a, b, c, D, Block[], , $6FA87E4F);
II(D, a, b, c, Block[], , $FE2CE6E0);
II(c, D, a, b, Block[], , $A3014314);
II(b, c, D, a, Block[], , $4E0811A1);
II(a, b, c, D, Block[], , $F7537E82);
II(D, a, b, c, Block[], , $BD3AF235);
II(c, D, a, b, Block[], , $2AD7D2BB);
II(b, c, D, a, Block[], , $EB86D391);
inc(State[], a);
inc(State[], b);
inc(State[], c);
inc(State[], D);
end;
procedure MD5Init(var Context: MD5Context);
begin
with Context do
begin
State[] := $;
State[] := $EFCDAB89;
State[] := $98BADCFE;
State[] := $;
Count[] := ;
Count[] := ;
ZeroMemory(@Buffer, SizeOf(MD5Buffer));
end;
end;
procedure MD5Update(var Context: MD5Context; Input: PAnsiChar; Length: longword);
var
Index: longword;
PartLen: longword;
I: longword;
begin
with Context do
begin
Index := (Count[] shr ) and $3F;
inc(Count[], Length shl );
if Count[] < (Length shl ) then
inc(Count[]);
inc(Count[], Length shr );
end;
PartLen := - Index;
if Length >= PartLen then
begin
CopyMemory(@Context.Buffer[Index], Input, PartLen);
Transform(@Context.Buffer, Context.State);
I := PartLen;
while I + < Length do
begin
Transform(@Input[I], Context.State);
inc(I, );
end;
Index := ;
end
else
I := ;
CopyMemory(@Context.Buffer[Index], @Input[I], Length - I);
end;
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
var
Bits: MD5CBits;
Index: longword;
PadLen: longword;
begin
Decode(@Context.Count, @Bits, );
Index := (Context.Count[] shr ) and $3F;
if Index < then
PadLen := - Index
else
PadLen := - Index;
MD5Update(Context, @PADDING, PadLen);
MD5Update(Context, @Bits, );
Decode(@Context.State, @Digest, );
ZeroMemory(@Context, SizeOf(MD5Context));
end;
function MD5String(M: AnsiString): MD5Digest;
var
Context: MD5Context;
begin
MD5Init(Context);
MD5Update(Context, PAnsiChar(M), Length(M));
MD5Final(Context, Result);
end;
function MD5File(N: string): MD5Digest;
var
FileHandle: THandle;
MapHandle: THandle;
ViewPointer: pointer;
Context: MD5Context;
begin
MD5Init(Context);
FileHandle := CreateFile(PWideChar(WideString(N)), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, );
if FileHandle <> INVALID_HANDLE_VALUE then
try
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, , , nil);
if MapHandle <> then
try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, , , );
if ViewPointer <> nil then
try
MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil));
finally
UnmapViewOfFile(ViewPointer);
end;
finally
CloseHandle(MapHandle);
end;
finally
CloseHandle(FileHandle);
end;
MD5Final(Context, Result);
end;
function MD5Print(D: MD5Digest): AnsiString;
var
I: Byte;
const
Digits: array[..] of Ansichar = ('', '', '', '', '', '', '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f');
begin
Result := '';
for I := to do
Result := Result + Digits[(D[I] shr ) and $0F] + Digits[D[I] and $0F];
end;
function MD5Match(D1, D2: MD5Digest): boolean;
var
I: Byte;
begin
I := ;
Result := TRUE;
while Result and (I < ) do
begin
Result := D1[I] = D2[I];
inc(I);
end;
end;
function MD5F(FileName: AnsiString): AnsiString;
begin
Result := MD5Print(MD5File(string(FileName)));
end;
function MD5S(Str: AnsiString): AnsiString;
begin
Result := MD5Print(MD5String(Str));
end;
function GetRamdomText(len: Integer): string;
var
I: Integer;
begin
Result := '';
Randomize;
for I := to Len - do
begin
Result := Result + Char( + Random());
end;
end;
function MD5FileText(filename: AnsiString): AnsiString;
var
buf: array[..MAX_PATH - ] of Char;
path: AnsiString;
stream: TFileStream;
destStream: TMemoryStream;
destfile: string;
tmpText: string;
strstream: TStringStream;
begin
GetTempPath(Length(buf), @buf[]);
path := AnsiString(string(buf));
tmpText := ExtractFileName(filename);
tmpText := Copy(tmpText, , Length(tmpText) - );
strstream := TStringStream.Create(tmpText, TEncoding.UTF8);
strstream.Position := ;
stream := TFileStream.Create(filename, fmOpenRead);
try
destStream := TMemoryStream.Create;
try
stream.Position := ;
destStream.CopyFrom(stream, stream.Size);
destfile := path + '\\' + GetRamdomText();
if FileExists(destfile) then
DeleteFile(destfile);
destStream.CopyFrom(strstream, strstream.Size);
destStream.SaveToFile(destfile);
strstream.Free;
Result := MD5F(destfile);
finally
destStream.Free;
end;
finally
stream.Free;
end;
if FileExists(destfile) then
DeleteFile(destfile);
end;
end.
手机扫一扫
移动阅读更方便
你可能感兴趣的文章