求一段 DELPHI下的 函数式的MD5加密算法(50分)

  • 主题发起人 主题发起人 Chinester
  • 开始时间 开始时间
C

Chinester

Unregistered / Unconfirmed
GUEST, unregistred user!
需要对 一些字符串进行操作 谢谢
 
unit md5;
interface
uses
Windows;
type
MD5Count = array[0..1] of DWORD;
MD5State = array[0..3] of DWORD;
MD5Block = array[0..15] of DWORD;
MD5CBits = array[0..7] of byte;
MD5Digest = array[0..15] of byte;
MD5Buffer = array[0..63] of byte;
MD5Context = record
State: MD5State;
Count: MD5Count;
Buffer: MD5Buffer;
end;
procedure MD5Init(var Context: MD5Context);
procedure MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
function MD5String(M: string): MD5Digest;
function MD5File(N: string): MD5Digest;
function MD5Print(D: MD5Digest): string;
function MD5Match(D1, D2: MD5Digest): boolean;
// -----------------------------------------------------------------------------------------------
IMPLEMENTATION
// -----------------------------------------------------------------------------------------------
var
PADDING: MD5Buffer = (
$80, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00
);
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;
begin
Result := y xor (x or (not z));
end;
procedure rot(var x: DWORD; n: BYTE);
begin
x := (x shl n) or (x shr (32 - 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;
// -----------------------------------------------------------------------------------------------
// 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;
// Transform State according to first 64 bytes at Buffer
procedure Transform(Buffer: pointer; var State: MD5State);
var
a, b, c, d: DWORD;
Block: MD5Block;
begin
Encode(Buffer, @Block, 64);
a := State[0];
b := State[1];
c := State[2];
d := State[3];
FF (a, b, c, d, Block[ 0], 7, $d76aa478);
FF (d, a, b, c, Block[ 1], 12, $e8c7b756);
FF (c, d, a, b, Block[ 2], 17, $242070db);
FF (b, c, d, a, Block[ 3], 22, $c1bdceee);
FF (a, b, c, d, Block[ 4], 7, $f57c0faf);
FF (d, a, b, c, Block[ 5], 12, $4787c62a);
FF (c, d, a, b, Block[ 6], 17, $a8304613);
FF (b, c, d, a, Block[ 7], 22, $fd469501);
FF (a, b, c, d, Block[ 8], 7, $698098d8);
FF (d, a, b, c, Block[ 9], 12, $8b44f7af);
FF (c, d, a, b, Block[10], 17, $ffff5bb1);
FF (b, c, d, a, Block[11], 22, $895cd7be);
FF (a, b, c, d, Block[12], 7, $6b901122);
FF (d, a, b, c, Block[13], 12, $fd987193);
FF (c, d, a, b, Block[14], 17, $a679438e);
FF (b, c, d, a, Block[15], 22, $49b40821);
GG (a, b, c, d, Block[ 1], 5, $f61e2562);
GG (d, a, b, c, Block[ 6], 9, $c040b340);
GG (c, d, a, b, Block[11], 14, $265e5a51);
GG (b, c, d, a, Block[ 0], 20, $e9b6c7aa);
GG (a, b, c, d, Block[ 5], 5, $d62f105d);
GG (d, a, b, c, Block[10], 9, $2441453);
GG (c, d, a, b, Block[15], 14, $d8a1e681);
GG (b, c, d, a, Block[ 4], 20, $e7d3fbc8);
GG (a, b, c, d, Block[ 9], 5, $21e1cde6);
GG (d, a, b, c, Block[14], 9, $c33707d6);
GG (c, d, a, b, Block[ 3], 14, $f4d50d87);
GG (b, c, d, a, Block[ 8], 20, $455a14ed);
GG (a, b, c, d, Block[13], 5, $a9e3e905);
GG (d, a, b, c, Block[ 2], 9, $fcefa3f8);
GG (c, d, a, b, Block[ 7], 14, $676f02d9);
GG (b, c, d, a, Block[12], 20, $8d2a4c8a);
HH (a, b, c, d, Block[ 5], 4, $fffa3942);
HH (d, a, b, c, Block[ 8], 11, $8771f681);
HH (c, d, a, b, Block[11], 16, $6d9d6122);
HH (b, c, d, a, Block[14], 23, $fde5380c);
HH (a, b, c, d, Block[ 1], 4, $a4beea44);
HH (d, a, b, c, Block[ 4], 11, $4bdecfa9);
HH (c, d, a, b, Block[ 7], 16, $f6bb4b60);
HH (b, c, d, a, Block[10], 23, $bebfbc70);
HH (a, b, c, d, Block[13], 4, $289b7ec6);
HH (d, a, b, c, Block[ 0], 11, $eaa127fa);
HH (c, d, a, b, Block[ 3], 16, $d4ef3085);
HH (b, c, d, a, Block[ 6], 23, $4881d05);
HH (a, b, c, d, Block[ 9], 4, $d9d4d039);
HH (d, a, b, c, Block[12], 11, $e6db99e5);
HH (c, d, a, b, Block[15], 16, $1fa27cf8);
HH (b, c, d, a, Block[ 2], 23, $c4ac5665);
II (a, b, c, d, Block[ 0], 6, $f4292244);
II (d, a, b, c, Block[ 7], 10, $432aff97);
II (c, d, a, b, Block[14], 15, $ab9423a7);
II (b, c, d, a, Block[ 5], 21, $fc93a039);
II (a, b, c, d, Block[12], 6, $655b59c3);
II (d, a, b, c, Block[ 3], 10, $8f0ccc92);
II (c, d, a, b, Block[10], 15, $ffeff47d);
II (b, c, d, a, Block[ 1], 21, $85845dd1);
II (a, b, c, d, Block[ 8], 6, $6fa87e4f);
II (d, a, b, c, Block[15], 10, $fe2ce6e0);
II (c, d, a, b, Block[ 6], 15, $a3014314);
II (b, c, d, a, Block[13], 21, $4e0811a1);
II (a, b, c, d, Block[ 4], 6, $f7537e82);
II (d, a, b, c, Block[11], 10, $bd3af235);
II (c, d, a, b, Block[ 2], 15, $2ad7d2bb);
II (b, c, d, a, Block[ 9], 21, $eb86d391);
inc(State[0], a);
inc(State[1], b);
inc(State[2], c);
inc(State[3], d);
end;
// -----------------------------------------------------------------------------------------------
// Initialize given Context
procedure MD5Init(var Context: MD5Context);
begin
with Context do begin
State[0] := $67452301;
State[1] := $efcdab89;
State[2] := $98badcfe;
State[3] := $10325476;
Count[0] := 0;
Count[1] := 0;
ZeroMemory(@Buffer, SizeOf(MD5Buffer));
end;
end;
// Update given Context to include Length bytes of Input
procedure MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
var
Index: longword;
PartLen: longword;
I: longword;
begin
with Context do begin
Index := (Count[0] shr 3) and $3f;
inc(Count[0], Length shl 3);
if Count[0] < (Length shl 3) then inc(Count[1]);
inc(Count[1], Length shr 29);
end;
PartLen := 64 - Index;
if Length >= PartLen then begin
CopyMemory(@Context.Buffer[Index], Input, PartLen);
Transform(@Context.Buffer, Context.State);
I := PartLen;
while I + 63 < Length do begin
Transform(@Input, Context.State);
inc(I, 64);
end;
Index := 0;
end else I := 0;
CopyMemory(@Context.Buffer[Index], @Input, Length - I);
end;
// Finalize given Context, create Digest and zeroize Context
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
var
Bits: MD5CBits;
Index: longword;
PadLen: longword;
begin
Decode(@Context.Count, @Bits, 2);
Index := (Context.Count[0] shr 3) and $3f;
if Index < 56 then PadLen := 56 - Index else PadLen := 120 - Index;
MD5Update(Context, @PADDING, PadLen);
MD5Update(Context, @Bits, 8);
Decode(@Context.State, @Digest, 4);
ZeroMemory(@Context, SizeOf(MD5Context));
end;
// -----------------------------------------------------------------------------------------------
// Create digest of given Message
function MD5String(M: string): MD5Digest;
var
Context: MD5Context;
begin
MD5Init(Context);
MD5Update(Context, pChar(M), length(M));
MD5Final(Context, Result);
end;
// Create digest of file with given Name
function MD5File(N: string): MD5Digest;
var
FileHandle: THandle;
MapHandle: THandle;
ViewPointer: pointer;
Context: MD5Context;
begin
MD5Init(Context);
FileHandle := CreateFile(pChar(N), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <>INVALID_HANDLE_VALUE then try
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <>0 then try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
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;
// Create hex representation of given Digest
function MD5Print(D: MD5Digest): string;
var
I: byte;
const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
begin
Result := '';
for I := 0 to 15 do Result := Result + Digits[(D shr 4) and $0f] + Digits[D and $0f];
end;
// -----------------------------------------------------------------------------------------------
// Compare two Digests
function MD5Match(D1, D2: MD5Digest): boolean;
var
I: byte;
begin
I := 0;
Result := TRUE;
while Result and (I < 16) do begin
Result := D1 = D2;
inc(I);
end;
end;
end.
 
unit Md5p;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;


type
MD5Count = array[0..1] of DWORD;
MD5State = array[0..3] of DWORD;
MD5Block = array[0..15] of DWORD;
MD5CBits = array[0..7] of Byte;
MD5Digest = array[0..15] of Byte;
MD5Buffer = array[0..63] of Byte;
MD5Context = record
State: MD5State;
Count: MD5Count;
Buffer: MD5Buffer;
end;


Function SecretD52(Str : String):String;
procedure MD5Init(var Context: MD5Context);
procedure MD5Update(var Context: MD5Context; Input: Pchar; Length: longword);
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);

function MD5String(M: string): MD5Digest;
function MD5File(N: string): MD5Digest;
function MD5Print(D: MD5Digest): string;
function MD5Match(D1, D2: MD5Digest): Boolean;

function RivestStr(Str: string): string;
function RivestFile(FileName: string): string;


var
PADDING: MD5Buffer = (
$80, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00);

implementation

Function SecretD52(Str : String):String;
var
s: string ;
begin
s:=RivestStr(str);
result:=s;
end;


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;
begin
Result := y xor (x or (not z));
end;

procedure rot(var x: DWORD; n: BYTE);
begin
x := (x shl n) or (x shr (32 - 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 := 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;

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;

procedure Transform(Buffer: pointer; var State: MD5State);
var
a, b, c, d: DWORD;
Block: MD5Block;
begin
Encode(Buffer, @Block, 64);
a := State[0];
b := State[1];
c := State[2];
d := State[3];
FF (a, b, c, d, Block[ 0], 7, $d76aa478);
FF (d, a, b, c, Block[ 1], 12, $e8c7b756);
FF (c, d, a, b, Block[ 2], 17, $242070db);
FF (b, c, d, a, Block[ 3], 22, $c1bdceee);
FF (a, b, c, d, Block[ 4], 7, $f57c0faf);
FF (d, a, b, c, Block[ 5], 12, $4787c62a);
FF (c, d, a, b, Block[ 6], 17, $a8304613);
FF (b, c, d, a, Block[ 7], 22, $fd469501);
FF (a, b, c, d, Block[ 8], 7, $698098d8);
FF (d, a, b, c, Block[ 9], 12, $8b44f7af);
FF (c, d, a, b, Block[10], 17, $ffff5bb1);
FF (b, c, d, a, Block[11], 22, $895cd7be);
FF (a, b, c, d, Block[12], 7, $6b901122);
FF (d, a, b, c, Block[13], 12, $fd987193);
FF (c, d, a, b, Block[14], 17, $a679438e);
FF (b, c, d, a, Block[15], 22, $49b40821);
GG (a, b, c, d, Block[ 1], 5, $f61e2562);
GG (d, a, b, c, Block[ 6], 9, $c040b340);
GG (c, d, a, b, Block[11], 14, $265e5a51);
GG (b, c, d, a, Block[ 0], 20, $e9b6c7aa);
GG (a, b, c, d, Block[ 5], 5, $d62f105d);
GG (d, a, b, c, Block[10], 9, $2441453);
GG (c, d, a, b, Block[15], 14, $d8a1e681);
GG (b, c, d, a, Block[ 4], 20, $e7d3fbc8);
GG (a, b, c, d, Block[ 9], 5, $21e1cde6);
GG (d, a, b, c, Block[14], 9, $c33707d6);
GG (c, d, a, b, Block[ 3], 14, $f4d50d87);
GG (b, c, d, a, Block[ 8], 20, $455a14ed);
GG (a, b, c, d, Block[13], 5, $a9e3e905);
GG (d, a, b, c, Block[ 2], 9, $fcefa3f8);
GG (c, d, a, b, Block[ 7], 14, $676f02d9);
GG (b, c, d, a, Block[12], 20, $8d2a4c8a);
HH (a, b, c, d, Block[ 5], 4, $fffa3942);
HH (d, a, b, c, Block[ 8], 11, $8771f681);
HH (c, d, a, b, Block[11], 16, $6d9d6122);
HH (b, c, d, a, Block[14], 23, $fde5380c);
HH (a, b, c, d, Block[ 1], 4, $a4beea44);
HH (d, a, b, c, Block[ 4], 11, $4bdecfa9);
HH (c, d, a, b, Block[ 7], 16, $f6bb4b60);
HH (b, c, d, a, Block[10], 23, $bebfbc70);
HH (a, b, c, d, Block[13], 4, $289b7ec6);
HH (d, a, b, c, Block[ 0], 11, $eaa127fa);
HH (c, d, a, b, Block[ 3], 16, $d4ef3085);
HH (b, c, d, a, Block[ 6], 23, $4881d05);
HH (a, b, c, d, Block[ 9], 4, $d9d4d039);
HH (d, a, b, c, Block[12], 11, $e6db99e5);
HH (c, d, a, b, Block[15], 16, $1fa27cf8);
HH (b, c, d, a, Block[ 2], 23, $c4ac5665);
II (a, b, c, d, Block[ 0], 6, $f4292244);
II (d, a, b, c, Block[ 7], 10, $432aff97);
II (c, d, a, b, Block[14], 15, $ab9423a7);
II (b, c, d, a, Block[ 5], 21, $fc93a039);
II (a, b, c, d, Block[12], 6, $655b59c3);
II (d, a, b, c, Block[ 3], 10, $8f0ccc92);
II (c, d, a, b, Block[10], 15, $ffeff47d);
II (b, c, d, a, Block[ 1], 21, $85845dd1);
II (a, b, c, d, Block[ 8], 6, $6fa87e4f);
II (d, a, b, c, Block[15], 10, $fe2ce6e0);
II (c, d, a, b, Block[ 6], 15, $a3014314);
II (b, c, d, a, Block[13], 21, $4e0811a1);
II (a, b, c, d, Block[ 4], 6, $f7537e82);
II (d, a, b, c, Block[11], 10, $bd3af235);
II (c, d, a, b, Block[ 2], 15, $2ad7d2bb);
II (b, c, d, a, Block[ 9], 21, $eb86d391);
inc(State[0], a);
inc(State[1], b);
inc(State[2], c);
inc(State[3], d);
end;

procedure MD5Init(var Context: MD5Context);
begin
with Context do begin
State[0] := $67452301;
State[1] := $efcdab89;
State[2] := $98badcfe;
State[3] := $10325476;
Count[0] := 0;
Count[1] := 0;
ZeroMemory(@Buffer, SizeOf(MD5Buffer));
end;
end;

procedure MD5Update(var Context: MD5Context; Input: Pchar; Length: longword);
var
Index: longword;
PartLen: longword;
I: longword;
begin
with Context do begin
Index := (Count[0] shr 3) and $3f;
inc(Count[0], Length shl 3);
if Count[0] < (Length shl 3) then inc(Count[1]);
inc(Count[1], Length shr 29);
end;
PartLen := 64 - Index;
if Length >= PartLen then begin
CopyMemory(@Context.Buffer[Index], Input, PartLen);
Transform(@Context.Buffer, Context.State);
I := PartLen;
while I + 63 < Length do begin
Transform(@Input, Context.State);
inc(I, 64);
end;
Index := 0;
end else I := 0;
CopyMemory(@Context.Buffer[Index], @Input, Length - I);
end;

procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
var
Bits: MD5CBits;
Index: longword;
PadLen: longword;
begin
Decode(@Context.Count, @Bits, 2);
Index := (Context.Count[0] shr 3) and $3f;
if Index < 56 then PadLen := 56 - Index else PadLen := 120 - Index;
MD5Update(Context, @PADDING, PadLen);
MD5Update(Context, @Bits, 8);
Decode(@Context.State, @Digest, 4);
ZeroMemory(@Context, SizeOf(MD5Context));
end;

function MD5String(M: string): MD5Digest;
var
Context: MD5Context;
begin
MD5Init(Context);
MD5Update(Context, pChar(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(pChar(N), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <> INVALID_HANDLE_VALUE then try
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
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): string;
var
I: byte;
const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
begin
Result := '';
for I := 0 to 15 do Result := Result + Digits[(D shr 4) and $0f] + Digits[D and $0f];
end;

function MD5Match(D1, D2: MD5Digest): boolean;
var
I: byte;
begin
I := 0;
Result := TRUE;
while Result and (I < 16) do begin
Result := D1 = D2;
inc(I);
end;
end;

function RivestStr(Str: string): string;
begin
Result := MD5Print(MD5String(Str));
end;

function RivestFile(FileName: string): string;
begin
Result := MD5Print(MD5File(FileName));
end;

end.



Function SecretD52(Str : String):String; 是对外的接口
 
http://www.steven-studio.com/forum/viewthread.php?tid=83
完整内容。
 
问题: delphi 求md5算法解释(不好意思,我只有45分了) ( 积分: 45 )
分类: 软件工程

来自: siso, 时间: 2005-01-18 10:34:00, ID: 2968492
我初学delphi
想学习md5 算法,首先问一下为什么md5有32位和16位两种,是否32位较好.
第二我从网上或论坛看到一下md5算法:
UNIT: MD5Unit

Sample:
procedure TForm1.Button1Click(Sender: TObject);
var
MD5Hash: TMD5;
OutputArray: array[0..15] of Char;
begin
MD5Hash := TMD5.Create;
try
MD5Hash.InputType := itString;
MD5Hash.InputString := Edit1.Text;
MD5Hash.POutputArray := @OutputArray;
MD5Hash.HashCalc;
Edit1.Text := OutputArray;
finally
MD5Hash.Free;
end;
end;
-------------------------------------------------------------------------------}
unit MD5Unit;

interface

uses SysUtils;

type
PLong = ^Longword;
TInputType = (itString, itFile, itByteArray);

PHashDigest = ^THashDigest;
THashDigest = record
A,
B,
C,
D: Longword;
end;

TMD5 = class
private
FInputType: TInputType;
FInputString: string;
FInputFilePath: string;
FPInputArray: PByteArray;
FInputLength: Longword;
FOutputDigest: PHashDigest;
FActiveBlock: array[0..15] of Longword;
FA, FB, FC, FD, FAA, FBB, FCC, FDD: Longword;
FpA, FpB, FpC, FpD: PLong;
procedure FF(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
procedure GG(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
procedure HH(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
procedure II(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
public
procedure HashInit;
procedure HashTransform;
procedure HashFinish;
procedure HashBytes;
procedure HashFile;
procedure HashCalc;
property InputType: TInputType read FInputType write FInputType;
property InputString: string read FInputString write FInputString;
property InputFilePath: string read FInputFilePath write FInputFilePath;
property PInputArray: PByteArray read FPInputArray write FPInputArray;
property InputLength: Longword read FInputLength write FInputLength;
property POutputArray: PHashDigest read FOutputDigest write FOutputDigest;
end;

const
S11 = 7;
S12 = 12;
S13 = 17;
S14 = 22;
S21 = 5;
S22 = 9;
S23 = 14;
S24 = 20;
S31 = 4;
S32 = 11;
S33 = 16;
S34 = 23;
S41 = 6;
S42 = 10;
S43 = 15;
S44 = 21;

implementation

function ROL(val: Longword; shift: Byte): LongWord; assembler;
asm
MOV EAX, val;
MOV CL, shift;
ROL EAX, CL;
end;

procedure TMD5.HashInit;
var
a, b, c, d: Longword;
begin
a := $67452301;
b := $efcdab89;
c := $98badcfe;
d := $10325476;
Move(a, FA, 4);
FpA := @FA;
Move(b, FB, 4);
FpB := @FB;
Move(c, FC, 4);
FpC := @FC;
Move(d, FD, 4);
FpD := @FD;
end;

{Purpose: Round 1 of the Transform.
Equivalent to a = b + ((a + F(b,c,d) + x + ac) <<< s)
Where F(b,c,d) = b And c Or Not(b) And d}
procedure TMD5.FF(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
var
Fret: Longword;
begin
Fret := ((PLong(b)^) and (PLong(c)^)) or ((not(PLong(b)^)) and (PLong(d)^));
PLong(a)^ := PLong(a)^ + Fret + PLong(x)^ + ac;
Longword(a^) := ROL(Longword(a^), s);
Inc(PLong(a)^, PLong(b)^);
end;

{Purpose: Round 2 of the Transform.
Equivalent to a = b + ((a + G(b,c,d) + x + ac) <<< s)
Where G(b,c,d) = b And d Or c Not d}
procedure TMD5.GG(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
var
Gret: Longword;
begin
Gret := (PLong(b)^ and PLong(d)^) or ( PLong(c)^ and (not PLong(d)^));
PLong(a)^ := PLong(a)^ + Gret + PLong(x)^ + ac;
Longword(a^) := ROL(Longword(a^), s);
Inc(PLong(a)^, PLong(b)^);
end;

{Purpose: Round 3 of the Transform.
Equivalent to a = b + ((a + H(b,c,d) + x + ac) <<< s)
Where H(b,c,d) = b Xor c Xor d}
procedure TMD5.HH(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
var
Hret: Longword;
begin
Hret := PLong(b)^ xor PLong(c)^ xor PLong(d)^;
PLong(a)^ := PLong(a)^ + Hret + PLong(x)^ + ac;
Longword(a^) := ROL(Longword(a^), s);
PLong(a)^ := PLong(b)^ + PLong(a)^;
end;

{Purpose: Round 4 of the Transform.
Equivalent to a = b + ((a + I(b,c,d) + x + ac) <<< s)
Where I(b,c,d) = C Xor (b Or Not(d))}
procedure TMD5.II(a, b, c, d, x: Pointer; s: Byte; ac: Longword);
var
Iret: Longword;
begin
Iret := (PLong(c)^ xor (PLong(b)^ or (not PLong(d)^)));
PLong(a)^ := PLong(a)^ + Iret + PLong(x)^ + ac;
Longword(a^) := ROL(PLong(a)^, s );
PLong(a)^ := PLong(b)^ + PLong(a)^;
end;

{Purpose: Perform Step 4 of the algorithm. This is where all the important
stuff happens. This performs the rounds on a 64Byte Block. This
procedure should be called in a loop until all input data has been
transformed.}
procedure TMD5.HashTransform;
begin
FAA := FA;
FBB := FB;
FCC := FC;
FDD := FD;

{ Round 1 }
FF(FpA, FpB, FpC, FpD, @FActiveBlock[ 0], S11, $d76aa478); { 1 }
FF(FpD, FpA, FpB, FpC, @FActiveBlock[ 1], S12, $e8c7b756); { 2 }
FF(FpC, FpD, FpA, FpB, @FActiveBlock[ 2], S13, $242070db); { 3 }
FF(FpB, FpC, FpD, FpA, @FActiveBlock[ 3], S14, $c1bdceee); { 4 }
FF(FpA, FpB, FpC, FpD, @FActiveBlock[ 4], S11, $f57c0faf); { 5 }
FF(FpD, FpA, FpB, FpC, @FActiveBlock[ 5], S12, $4787c62a); { 6 }
FF(FpC, FpD, FpA, FpB, @FActiveBlock[ 6], S13, $a8304613); { 7 }
FF(FpB, FpC, FpD, FpA, @FActiveBlock[ 7], S14, $fd469501); { 8 }
FF(FpA, FpB, FpC, FpD, @FActiveBlock[ 8], S11, $698098d8); { 9 }
FF(FpD, FpA, FpB, FpC, @FActiveBlock[ 9], S12, $8b44f7af); { 10 }
FF(FpC, FpD, FpA, FpB, @FActiveBlock[10], S13, $ffff5bb1); { 11 }
FF(FpB, FpC, FpD, FpA, @FActiveBlock[11], S14, $895cd7be); { 12 }
FF(FpA, FpB, FpC, FpD, @FActiveBlock[12], S11, $6b901122); { 13 }
FF(FpD, FpA, FpB, FpC, @FActiveBlock[13], S12, $fd987193); { 14 }
FF(FpC, FpD, FpA, FpB, @FActiveBlock[14], S13, $a679438e); { 15 }
FF(FpB, FpC, FpD, FpA, @FActiveBlock[15], S14, $49b40821); { 16 }

{ Round 2 }
GG(FpA, FpB, FpC, FpD, @FActiveBlock[ 1], S21, $f61e2562); { 17 }
GG(FpD, FpA, FpB, FpC, @FActiveBlock[ 6], S22, $c040b340); { 18 }
GG(FpC, FpD, FpA, FpB, @FActiveBlock[11], S23, $265e5a51); { 19 }
GG(FpB, FpC, FpD, FpA, @FActiveBlock[ 0], S24, $e9b6c7aa); { 20 }
GG(FpA, FpB, FpC, FpD, @FActiveBlock[ 5], S21, $d62f105d); { 21 }
GG(FpD, FpA, FpB, FpC, @FActiveBlock[10], S22, $02441453); { 22 }
GG(FpC, FpD, FpA, FpB, @FActiveBlock[15], S23, $d8a1e681); { 23 }
GG(FpB, FpC, FpD, FpA, @FActiveBlock[ 4], S24, $e7d3fbc8); { 24 }
GG(FpA, FpB, FpC, FpD, @FActiveBlock[ 9], S21, $21e1cde6); { 25 }
GG(FpD, FpA, FpB, FpC, @FActiveBlock[14], S22, $c33707d6); { 26 }
GG(FpC, FpD, FpA, FpB, @FActiveBlock[ 3], S23, $f4d50d87); { 27 }
GG(FpB, FpC, FpD, FpA, @FActiveBlock[ 8], S24, $455a14ed); { 28 }
GG(FpA, FpB, FpC, FpD, @FActiveBlock[13], S21, $a9e3e905); { 29 }
GG(FpD, FpA, FpB, FpC, @FActiveBlock[ 2], S22, $fcefa3f8); { 30 }
GG(FpC, FpD, FpA, FpB, @FActiveBlock[ 7], S23, $676f02d9); { 31 }
GG(FpB, FpC, FpD, FpA, @FActiveBlock[12], S24, $8d2a4c8a); { 32 }

{ Round 3 }
HH(FpA, FpB, FpC, FpD, @FActiveBlock[ 5], S31, $fffa3942); { 33 }
HH(FpD, FpA, FpB, FpC, @FActiveBlock[ 8], S32, $8771f681); { 34 }
HH(FpC, FpD, FpA, FpB, @FActiveBlock[11], S33, $6d9d6122); { 35 }
HH(FpB, FpC, FpD, FpA, @FActiveBlock[14], S34, $fde5380c); { 36 }
HH(FpA, FpB, FpC, FpD, @FActiveBlock[ 1], S31, $a4beea44); { 37 }
HH(FpD, FpA, FpB, FpC, @FActiveBlock[ 4], S32, $4bdecfa9); { 38 }
HH(FpC, FpD, FpA, FpB, @FActiveBlock[ 7], S33, $f6bb4b60); { 39 }
HH(FpB, FpC, FpD, FpA, @FActiveBlock[10], S34, $bebfbc70); { 40 }
HH(FpA, FpB, FpC, FpD, @FActiveBlock[13], S31, $289b7ec6); { 41 }
HH(FpD, FpA, FpB, FpC, @FActiveBlock[ 0], S32, $eaa127fa); { 42 }
HH(FpC, FpD, FpA, FpB, @FActiveBlock[ 3], S33, $d4ef3085); { 43 }
HH(FpB, FpC, FpD, FpA, @FActiveBlock[ 6], S34, $04881d05); { 44 }
HH(FpA, FpB, FpC, FpD, @FActiveBlock[ 9], S31, $d9d4d039); { 45 }
HH(FpD, FpA, FpB, FpC, @FActiveBlock[12], S32, $e6db99e5); { 46 }
HH(FpC, FpD, FpA, FpB, @FActiveBlock[15], S33, $1fa27cf8); { 47 }
HH(FpB, FpC, FpD, FpA, @FActiveBlock[ 2], S34, $c4ac5665); { 48 }

{ Round 4 }
II(FpA, FpB, FpC, FpD, @FActiveBlock[ 0], S41, $f4292244); { 49 }
II(FpD, FpA, FpB, FpC, @FActiveBlock[ 7], S42, $432aff97); { 50 }
II(FpC, FpD, FpA, FpB, @FActiveBlock[14], S43, $ab9423a7); { 51 }
II(FpB, FpC, FpD, FpA, @FActiveBlock[ 5], S44, $fc93a039); { 52 }
II(FpA, FpB, FpC, FpD, @FActiveBlock[12], S41, $655b59c3); { 53 }
II(FpD, FpA, FpB, FpC, @FActiveBlock[ 3], S42, $8f0ccc92); { 54 }
II(FpC, FpD, FpA, FpB, @FActiveBlock[10], S43, $ffeff47d); { 55 }
II(FpB, FpC, FpD, FpA, @FActiveBlock[ 1], S44, $85845dd1); { 56 }
II(FpA, FpB, FpC, FpD, @FActiveBlock[ 8], S41, $6fa87e4f); { 57 }
II(FpD, FpA, FpB, FpC, @FActiveBlock[15], S42, $fe2ce6e0); { 58 }
II(FpC, FpD, FpA, FpB, @FActiveBlock[ 6], S43, $a3014314); { 59 }
II(FpB, FpC, FpD, FpA, @FActiveBlock[13], S44, $4e0811a1); { 60 }
II(FpA, FpB, FpC, FpD, @FActiveBlock[ 4], S41, $f7537e82); { 61 }
II(FpD, FpA, FpB, FpC, @FActiveBlock[11], S42, $bd3af235); { 62 }
II(FpC, FpD, FpA, FpB, @FActiveBlock[ 2], S43, $2ad7d2bb); { 63 }
II(FpB, FpC, FpD, FpA, @FActiveBlock[ 9], S44, $eb86d391); { 64 }

Inc(FA, FAA);
Inc(FB, FBB);
Inc(FC, FCC);
Inc(FD, FDD);

FillChar(FActiveBlock, SizeOf(FActiveBlock), #0);
end;

procedure TMD5.HashCalc;
var
PStr: PChar;
begin
HashInit;
case FInputType of
itFile:
HashFile;
itByteArray:
HashBytes;
itString:
begin
PStr := StrAlloc(Length(FInputString) + 1);
try
StrPCopy(PStr, FInputString);
FInputLength := Length(FInputString);
FPInputArray := Pointer(PStr);
HashBytes;
finally
StrDispose(PStr);
end;
end;
end;
HashFinish;
end;

procedure TMD5.HashBytes;
var
Buffer: array[0..4159] of Byte;
Count64: Comp;
Index: Longword;
begin
Move(FPInputArray^, Buffer, FInputLength);
Count64 := FInputLength * 8;
Buffer[FInputLength] := $80;
Inc(FInputLength);
while (FInputLength mod 64) <> 56 do
begin
Buffer[FInputLength] := 0;
Inc(FInputLength);
end;
Move(Count64, Buffer[FInputLength], SizeOf(Count64));
Index := 0;
Inc(FInputLength, 8);
repeat
Move(Buffer[Index], FActiveBlock, 64);
HashTransform;
Inc(Index, 64);
until Index = FInputLength;
end;

procedure TMD5.HashFile;
var
DoneFile: Boolean;
InputFile: file;
Count64: Comp;
Index, NumRead: Integer;
Buffer: array[0..4159] of Byte;
begin
DoneFile := False;
AssignFile(InputFile, FInputFilePath);
Reset(InputFile, 1);
Count64 := 0;
repeat
BlockRead(InputFile, Buffer, 4096, NumRead);
Count64 := Count64 + NumRead;
if NumRead <> 4096 then
begin
Buffer[NumRead] := $80;
Inc(NumRead);
while (NumRead mod 64) <> 56 do
begin
Buffer[NumRead] := 0;
Inc(NumRead);
end;
Count64 := Count64 * 8;
Move(Count64, Buffer[NumRead], 8);
Inc(NumRead, 8);
DoneFile := True;
end;
Index := 0;
repeat
Move(Buffer[Index], FActiveBlock, 64);
HashTransform;
Inc(Index, 64);
until Index = NumRead;
until DoneFile;
CloseFile(InputFile);
end;

procedure TMD5.HashFinish;
begin
FOutputDigest^.A := Longword(FpA^);
FOutputDigest^.B := Longword(FpB^);
FOutputDigest^.C := Longword(FpC^);
FOutputDigest^.D := Longword(FpD^);
end;

end.
可是不知怎么用(我把以上代码复制到delphi,可总不能编译)而且也不知代码的意思,请各位指点一下.谢谢!!!


来自: 程胜, 时间: 2005-01-18 18:05:06, ID: 2969163
转载:
  md5的全称是message-digest algorithm 5(信息-摘要算法),在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest开发出来,经md2、md3和md4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。不管是md2、md4还是md5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。虽然这些算法的结构或多或少有些相似,但md2的设计与md4和md5完全不同,那是因为md2是为8位机器做过设计优化的,而md4和md5却是面向32位的电脑。这三个算法的描述和c语言源代码在internet rfcs 1321中有详细的描述(http://www.ietf.org/rfc/rfc1321.txt),这是一份最权威的文档,由ronald l. rivest在1992年8月向ieft提交。

  rivest在1989年开发出md2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的检验和追加到信息末尾。并且根据这个新产生的信息计算出散列值。后来,rogier和chauvaud发现如果忽略了检验和将产生md2冲突。md2算法的加密后结果是唯一的--既没有重复。

  为了加强算法的安全性,rivest在1990年又开发出md4算法。md4算法同样需要填补信息以确保信息的字节长度加上448后能被512整除(信息字节长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damg?rd/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。den boer和bosselaers以及其他人很快的发现了攻击md4版本中第一步和第三步的漏洞。dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到md4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)。毫无疑问,md4就此被淘汰掉了。

  尽管md4算法在安全上有个这么大的漏洞,但它对在其后才被开发出来的好几种信息安全加密算法的出现却有着不可忽视的引导作用。除了md5以外,其中比较有名的还有sha-1、ripe-md以及haval等。

  一年以后,即1991年,rivest开发出技术上更为趋近成熟的md5算法。它在md4的基础上增加了"安全-带子"(safety-belts)的概念。虽然md5比md4稍微慢一些,但却更为安全。这个算法很明显的由四个和md4设计有少许不同的步骤组成。在md5算法中,信息-摘要的大小和填充的必要条件与md4完全相同。den boer和bosselaers曾发现md5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。

  van oorschot和wiener曾经考虑过一个在散列中暴力搜寻冲突的函数(brute-force hash function),而且他们猜测一个被设计专门用来搜索md5冲突的机器(这台机器在1994年的制造成本大约是一百万美元)可以平均每24天就找到一个冲突。但单从1991年到2001年这10年间,竟没有出现替代md5算法的md6或被叫做其他什么名字的新算法这一点,我们就可以看出这个瑕疵并没有太多的影响md5的安全性。上面所有这些都不足以成为md5的在实际应用中的问题。并且,由于md5算法的使用不需要支付任何版权费用的,所以在一般的情况下(非绝密应用领域。但即便是应用在绝密领域内,md5也不失为一种非常优秀的中间技术),md5怎么都应该算得上是非常安全的了。

  算法的应用

  md5的典型应用是对一段信息(message)产生信息摘要(message-digest),以防止被篡改。比如,在unix下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如:

   md5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461

  这就是tanajiya.tar.gz文件的数字签名。md5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的md5信息摘要。如果在以后传播这个文件的过程中,无论文件的内容发生了任何形式的改变(包括人为修改或者下载过程中线路不稳定引起的传输错误等),只要你对这个文件重新计算md5时就会发现信息摘要不相同,由此可以确定你得到的只是一个不正确的文件。如果再有一个第三方的认证机构,用md5还可以防止文件作者的"抵赖",这就是所谓的数字签名应用。

  md5还广泛用于加密和解密技术上。比如在unix系统中用户的密码就是以md5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成md5值,然后再去和保存在文件系统中的md5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。

  正是因为这个原因,现在被黑客使用最多的一种破译密码的方法就是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用md5程序计算出这些字典项的md5值,然后再用目标的md5值在这个字典中检索。我们假设密码的最大长度为8位字节(8 bytes),同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是p(62,1)+p(62,2)….+p(62,8),那也已经是一个很天文的数字了,存储这个字典就需要tb级的磁盘阵列,而且这种方法还有一个前提,就是能获得目标账户的密码md5值的情况下才可以。这种加密技术被广泛的应用于unix系统中,这也是为什么unix系统比一般操作系统更为坚固一个重要原因。

  算法描述

  对md5算法简要的叙述可以为:md5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

  在md5算法中,首先需要对信息进行填充,使其字节长度对512求余的结果等于448。因此,信息的字节长度(bits length)将被扩展至n*512+448,即n*64+56个字节(bytes),n为一个正整数。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后,在在这个结果后面附加一个以64位二进制表示的填充前信息长度。经过这两步的处理,现在的信息字节长度=n*512+448+64=(n+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。

  md5中有四个32位被称作链接变量(chaining variable)的整数参数,他们分别为:a=0x01234567,b=0x89abcdef,c=0xfedcba98,d=0x76543210。

  当设置好这四个链接变量后,就开始进入算法的四轮循环运算。循环的次数是信息中512位信息分组的数目。

  将上面四个链接变量复制到另外四个变量中:a到a,b到b,c到c,d到d。

  主循环有四轮(md4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向右环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
以一下是每次操作中用到的四个非线性函数(每轮一个)。

   f(x,y,z) =(x&y)|((~x)&z)
   g(x,y,z) =(x&z)|(y&(~z))
   h(x,y,z) =x^y^z
   i(x,y,z)=y^(x|(~z))
   (&是与,|是或,~是非,^是异或)

  这四个函数的说明:如果x、y和z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
f是一个逐位运算的函数。即,如果x,那么y,否则z。函数h是逐位奇偶操作符。

  假设mj表示消息的第j个子分组(从0到15),<<
   ff(a,b,c,d,mj,s,ti)表示a=b+((a+(f(b,c,d)+mj+ti)<<    gg(a,b,c,d,mj,s,ti)表示a=b+((a+(g(b,c,d)+mj+ti)<<    hh(a,b,c,d,mj,s,ti)表示a=b+((a+(h(b,c,d)+mj+ti)<<    ii(a,b,c,d,mj,s,ti)表示a=b+((a+(i(b,c,d)+mj+ti)<<
  这四轮(64步)是:

  第一轮

   ff(a,b,c,d,m0,7,0xd76aa478)
   ff(d,a,b,c,m1,12,0xe8c7b756)
   ff(c,d,a,b,m2,17,0x242070db)
ff(b,c,d,a,m3,22,0xc1bdceee)
   ff(a,b,c,d,m4,7,0xf57c0faf)
   ff(d,a,b,c,m5,12,0x4787c62a)
   ff(c,d,a,b,m6,17,0xa8304613)
   ff(b,c,d,a,m7,22,0xfd469501)
   ff(a,b,c,d,m8,7,0x698098d8)
   ff(d,a,b,c,m9,12,0x8b44f7af)
   ff(c,d,a,b,m10,17,0xffff5bb1)
   ff(b,c,d,a,m11,22,0x895cd7be)
   ff(a,b,c,d,m12,7,0x6b901122)
   ff(d,a,b,c,m13,12,0xfd987193)
   ff(c,d,a,b,m14,17,0xa679438e)
   ff(b,c,d,a,m15,22,0x49b40821)

  第二轮

   gg(a,b,c,d,m1,5,0xf61e2562)
   gg(d,a,b,c,m6,9,0xc040b340)
   gg(c,d,a,b,m11,14,0x265e5a51)
   gg(b,c,d,a,m0,20,0xe9b6c7aa)
   gg(a,b,c,d,m5,5,0xd62f105d)
   gg(d,a,b,c,m10,9,0x02441453)
   gg(c,d,a,b,m15,14,0xd8a1e681)
   gg(b,c,d,a,m4,20,0xe7d3fbc8)
   gg(a,b,c,d,m9,5,0x21e1cde6)
   gg(d,a,b,c,m14,9,0xc33707d6)
   gg(c,d,a,b,m3,14,0xf4d50d87)
   gg(b,c,d,a,m8,20,0x455a14ed)
   gg(a,b,c,d,m13,5,0xa9e3e905)
   gg(d,a,b,c,m2,9,0xfcefa3f8)
   gg(c,d,a,b,m7,14,0x676f02d9)
   gg(b,c,d,a,m12,20,0x8d2a4c8a)

  第三轮

   hh(a,b,c,d,m5,4,0xfffa3942)
   hh(d,a,b,c,m8,11,0x8771f681)
   hh(c,d,a,b,m11,16,0x6d9d6122)
   hh(b,c,d,a,m14,23,0xfde5380c)
   hh(a,b,c,d,m1,4,0xa4beea44)
   hh(d,a,b,c,m4,11,0x4bdecfa9)
   hh(c,d,a,b,m7,16,0xf6bb4b60)
   hh(b,c,d,a,m10,23,0xbebfbc70)
   hh(a,b,c,d,m13,4,0x289b7ec6)
   hh(d,a,b,c,m0,11,0xeaa127fa)
   hh(c,d,a,b,m3,16,0xd4ef3085)
   hh(b,c,d,a,m6,23,0x04881d05)
   hh(a,b,c,d,m9,4,0xd9d4d039)
   hh(d,a,b,c,m12,11,0xe6db99e5)
   hh(c,d,a,b,m15,16,0x1fa27cf8)
   hh(b,c,d,a,m2,23,0xc4ac5665)

  第四轮

   ii(a,b,c,d,m0,6,0xf4292244)
   ii(d,a,b,c,m7,10,0x432aff97)
   ii(c,d,a,b,m14,15,0xab9423a7)
   ii(b,c,d,a,m5,21,0xfc93a039)
   ii(a,b,c,d,m12,6,0x655b59c3)
   ii(d,a,b,c,m3,10,0x8f0ccc92)
   ii(c,d,a,b,m10,15,0xffeff47d)
   ii(b,c,d,a,m1,21,0x85845dd1)
   ii(a,b,c,d,m8,6,0x6fa87e4f)
   ii(d,a,b,c,m15,10,0xfe2ce6e0)
   ii(c,d,a,b,m6,15,0xa3014314)
   ii(b,c,d,a,m13,21,0x4e0811a1)
   ii(a,b,c,d,m4,6,0xf7537e82)
   ii(d,a,b,c,m11,10,0xbd3af235)
   ii(c,d,a,b,m2,15,0x2ad7d2bb)
   ii(b,c,d,a,m9,21,0xeb86d391)

  常数ti可以如下选择:

  在第i步中,ti是4294967296*abs(sin(i))的整数部分,i的单位是弧度。(4294967296等于2的32次方)
所有这些完成之后,将a、b、c、d分别加上a、b、c、d。然后用下一分组数据继续运行算法,最后的输出是a、b、c和d的级联。

  当你按照我上面所说的方法实现md5算法以后,你可以用以下几个信息对你做出来的程序作一个简单的测试,看看程序有没有错误。

   md5 ("") = d41d8cd98f00b204e9800998ecf8427e
   md5 ("a") = 0cc175b9c0f1b6a831c399e269772661
   md5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
   md5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
   md5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
   md5 ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
   md5 ("123456789012345678901234567890123456789012345678901234567890123456789
01234567890") = 57edf4a22be3c955ac49da2e2107b67a

  如果你用上面的信息分别对你做的md5算法实例做测试,最后得出的结论和标准答案完全一样,那我就要在这里象你道一声祝贺了。要知道,我的程序在第一次编译成功的时候是没有得出和上面相同的结果的。


  md5的安全性

  md5相对md4所作的改进:

   1. 增加了第四轮;

   2. 每一步均有唯一的加法常数;

   3. 为减弱第二轮中函数g的对称性从(x&y)|(x&z)|(y&z)变为(x&z)|(y&(~z));

   4. 第一步加上了上一步的结果,这将引起更快的雪崩效应;

   5. 改变了第二轮和第三轮中访问消息子分组的次序,使其更不相似;

   6. 近似优化了每一轮中的循环左移位移量以实现更快的雪崩效应。各轮的位移量互不相同。

希望你还没有晕,呵呵!

来自: missinwind, 时间: 2005-01-18 18:31:46, ID: 2969221
两位好耐性,佩服!

来自: siso, 时间: 2005-01-19 8:53:51, ID: 2969607
程胜大哥!这个理论我就是看不懂才贴出来问.(结果你给我更多的理论[:(]
我想知道md516位和32位有何区别,是否32位比16位好.
还有我想知道上面的程序怎么用,我把他们全部复制,但不能用啊.谢谢

来自: qvbvj520, 时间: 2005-02-25 11:14:23, ID: 2997203
两位好耐性,佩服!再佩服《[:)]》

来自: shangchao, 时间: 2005-02-25 11:16:33, ID: 2997209
我晕!

来自: 32881, 时间: 2005-06-05 3:13:57, ID: 3094636
不知道啊,我是一个菜鸟而已哦!

来自: siso, 时间: 2005-09-10 17:17:49, ID: 3200251
多人接受答案了。

问题讨论没有结束 ...
 
问题: 求购MD5算法的源文件For Delphi6或者Dll什么的 ( 积分: 100 )
分类: 非技术问题

来自: tong_hui, 时间: 2002-05-09 9:51:00, ID: 1090418
求购MD5算法的源文件For Delphi6或者Dll什么的,最好带有例题了,还有delphi6中的indy带有的
md5怎么使用啊?

来自: bianlx, 时间: 2002-05-09 10:22:00, ID: 1090501
在2001程序员大本营--borland版的光盘上有这个算法

来自: happyzxj, 时间: 2002-06-02 20:34:00, ID: 1139106
我有ASP的:
注:以上内容可以生成128位的结果,但原作者为了把它放到自己的数据库中,
只取了中间的64位,这点你要注意一下。
另外,DELPHI的我也有,先给分我就告诉你。


MD5不可逆加密算法的ASP实现实例
2002-2-6 动网先锋

此为国外转载函数,可将任意字符转换为md5 16为字符加密形式,而且为不可逆转换。
<%
Private Const BITS_TO_A_BYTE = 8
Private Const BYTES_TO_A_WORD = 4
Private Const BITS_TO_A_WORD = 32

Private m_lOnBits(30)
Private m_l2Power(30)

Private Function LShift(lValue, iShiftBits)
If iShiftBits = 0 Then
LShift = lValue
Exit Function
ElseIf iShiftBits = 31 Then
If lValue And 1 Then
LShift = &H80000000
Else
LShift = 0
End If
Exit Function
ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
Err.Raise 6
End If

If (lValue And m_l2Power(31 - iShiftBits)) Then
LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1))) * m_l2Power(iShiftBits)) Or &H80000000
Else
LShift = ((lValue And m_lOnBits(31 - iShiftBits)) * m_l2Power(iShiftBits))
End If
End Function

Private Function RShift(lValue, iShiftBits)
If iShiftBits = 0 Then
RShift = lValue
Exit Function
ElseIf iShiftBits = 31 Then
If lValue And &H80000000 Then
RShift = 1
Else
RShift = 0
End If
Exit Function
ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
Err.Raise 6
End If

RShift = (lValue And &H7FFFFFFE) / m_l2Power(iShiftBits)

If (lValue And &H80000000) Then
RShift = (RShift Or (&H40000000 / m_l2Power(iShiftBits - 1)))
End If
End Function

Private Function RotateLeft(lValue, iShiftBits)
RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits))
End Function

Private Function AddUnsigned(lX, lY)
Dim lX4
Dim lY4
Dim lX8
Dim lY8
Dim lResult

lX8 = lX And &H80000000
lY8 = lY And &H80000000
lX4 = lX And &H40000000
lY4 = lY And &H40000000

lResult = (lX And &H3FFFFFFF) + (lY And &H3FFFFFFF)

If lX4 And lY4 Then
lResult = lResult Xor &H80000000 Xor lX8 Xor lY8
ElseIf lX4 Or lY4 Then
If lResult And &H40000000 Then
lResult = lResult Xor &HC0000000 Xor lX8 Xor lY8
Else
lResult = lResult Xor &H40000000 Xor lX8 Xor lY8
End If
Else
lResult = lResult Xor lX8 Xor lY8
End If

AddUnsigned = lResult
End Function

Private Function md5_F(x, y, z)
md5_F = (x And y) Or ((Not x) And z)
End Function

Private Function md5_G(x, y, z)
md5_G = (x And z) Or (y And (Not z))
End Function

Private Function md5_H(x, y, z)
md5_H = (x Xor y Xor z)
End Function

Private Function md5_I(x, y, z)
md5_I = (y Xor (x Or (Not z)))
End Function

Private Sub md5_FF(a, b, c, d, x, s, ac)
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_F(b, c, d), x), ac))
a = RotateLeft(a, s)
a = AddUnsigned(a, b)
End Sub

Private Sub md5_GG(a, b, c, d, x, s, ac)
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_G(b, c, d), x), ac))
a = RotateLeft(a, s)
a = AddUnsigned(a, b)
End Sub

Private Sub md5_HH(a, b, c, d, x, s, ac)
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_H(b, c, d), x), ac))
a = RotateLeft(a, s)
a = AddUnsigned(a, b)
End Sub

Private Sub md5_II(a, b, c, d, x, s, ac)
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_I(b, c, d), x), ac))
a = RotateLeft(a, s)
a = AddUnsigned(a, b)
End Sub

Private Function ConvertToWordArray(sMessage)
Dim lMessageLength
Dim lNumberOfWords
Dim lWordArray()
Dim lBytePosition
Dim lByteCount
Dim lWordCount

Const MODULUS_BITS = 512
Const CONGRUENT_BITS = 448

lMessageLength = Len(sMessage)

lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) / BITS_TO_A_BYTE)) / (MODULUS_BITS / BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS / BITS_TO_A_WORD)
ReDim lWordArray(lNumberOfWords - 1)

lBytePosition = 0
lByteCount = 0
Do Until lByteCount >= lMessageLength
lWordCount = lByteCount / BYTES_TO_A_WORD
lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(Asc(Mid(sMessage, lByteCount + 1, 1)), lBytePosition)
lByteCount = lByteCount + 1
Loop

lWordCount = lByteCount / BYTES_TO_A_WORD
lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE

lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80, lBytePo

来自: honestman, 时间: 2002-06-02 22:32:00, ID: 1139310
http://www.csdn.net/Dev/Delphi/vcl/vcltools/

来自: amsea, 时间: 2002-08-19 16:30:00, ID: 1273836
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
str1, str2: string;
begin
IdCoderMD51.Reset;
IdCoderMD51.AutoCompleteInput := True;
str1 := IdCoderMD51.CodeString('123456');
Delete(str1, 1, 2);
str2 := '';
for i := 0 to Length(str1) do
begin
str2 := str2 + LowerCase(IntToHex(BYTE(str1), 2));
end;

edit2.Text := str2;
end;

可以这样使用。
但是和asp下计算的算法得到的结果不一样。
不知道为什么。

来自: happyzxj, 时间: 2002-08-19 22:03:00, ID: 1274566
楼上的兄弟:你只给出用法有什么用啊。
另外,如果你有DELPHI的代码,并且得到的结果与我上面的ASP代码不同的话,
一定是你的代码不对。上面那段ASP代码是我从一个论坛的源代码里截取的,
并且我也有DELPHI的源代码,两者得出的结果是一样的。
我至所以不贴DELPHI的源代码,是有意想让读者费些力气,毕竞MD5算法不是实现
某个系统的关键(密码破解程序除外),将ASP代码转换成DELPHI代码有利于读者
更深刻地理解MD5算法。至于给分才给代码,是开玩笑而己。

来自: GuestUser, 时间: 2002-12-28 7:41:00, ID: 1543770
Re:happyzxj
给我MD5的DELPHI源代码,给你100分。

来自: 山泉, 时间: 2002-12-28 8:25:00, ID: 1543789
http://www.neweasier.com/vcl.html?class=35
多的是

来自: happyzxj, 时间: 2002-12-28 9:26:00, ID: 1543891
才给100分啊,不过,分多分少无所谓,还是给你吧。
ftp://zxj.vicp.net/md5
每天6:00-22:00开机,但有时(不经常)会因为各种原因而不能开机。
或者你给我你的E-MAIL
1735


来自: alextsui, 时间: 2002-12-30 15:17:00, ID: 1548932
/************************************************
MD5 算法的Java Bean
@author:Topcat Tuppin
Last Modified:10,Mar,2001
*************************************************/
package beartool;
import java.lang.reflect.*;
/*************************************************
md5 類實現了RSA Data Security, Inc.在提交給IETF
的RFC1321中的MD5 message-digest 算法。
*************************************************/

public class MD5 {
/* 下面這些S11-S44實際上是一個4*4的矩陣,在原始的C實現中是用#define 實現的,
這裡把它們實現成為static final是表示了隻讀,切能在同一個進程空間內的多個
Instance間共享*/
static final int S11 = 7;
static final int S12 = 12;
static final int S13 = 17;
static final int S14 = 22;

static final int S21 = 5;
static final int S22 = 9;
static final int S23 = 14;
static final int S24 = 20;

static final int S31 = 4;
static final int S32 = 11;
static final int S33 = 16;
static final int S34 = 23;

static final int S41 = 6;
static final int S42 = 10;
static final int S43 = 15;
static final int S44 = 21;

static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
/* 下面的三個成員是MD5計算過程中用到的3個核心數據,在原始的C實現中
被定義到MD5_CTX結構中

*/
private long[] state = new long[4]; // state (ABCD)
private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first)
private byte[] buffer = new byte[64]; // input buffer

/* digestHexStr是MD5的唯一一個公共成員,是最新一次計算結果的
16進制ASCII表示.
*/
public String digestHexStr;

/* digest,是最新一次計算結果的2進制內部表示,表示128bit的MD5值.
*/
private byte[] digest = new byte[16];

/*
getMD5ofStr是類MD5最主要的公共方法,入口參數是你想要進行MD5變換的字符串
返回的是變換完的結果,這個結果是從公共成員digestHexStr取得的﹒
*/
public String getMD5ofStr(String inbuf) {
md5Init();
md5Update(inbuf.getBytes(), inbuf.length());
md5Final();
digestHexStr = "";
for (int i = 0; i < 16; i++) {
digestHexStr += byteHEX(digest);
}
return digestHexStr;

}
// 這是MD5這個類的標準構造函數,JavaBean要求有一個public的並且沒有參數的構造函數
public MD5() {
md5Init();

return;
}



/* md5Init是一個初始化函數,初始化核心變量,裝入標準的幻數 */
private void md5Init() {
count[0] = 0L;
count[1] = 0L;
///* Load magic initialization constants.

state[0] = 0x67452301L;
state[1] = 0xefcdab89L;
state[2] = 0x98badcfeL;
state[3] = 0x10325476L;

return;
}
/* F, G, H ,I 是4個基本的MD5函數,在原始的MD5的C實現中,由於它們是
簡單的位運算,可能出於效率的考慮把它們實現成了宏,在java中,我們把它們
實現成了private方法,名字保持了原來C中的。 */

private long F(long x, long y, long z) {
return (x & y) | ((~x) & z);

}
private long G(long x, long y, long z) {
return (x & z) | (y & (~z));

}
private long H(long x, long y, long z) {
return x ^ y ^ z;
}

private long I(long x, long y, long z) {
return y ^ (x | (~z));
}

/*
FF,GG,HH和II將調用F,G,H,I進行近一步變換
FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/



来自: 叮叮当当, 时间: 2002-12-30 15:23:00, ID: 1548953
我有For Delphi6的MD5函数源代码,只需调用该Pas中的一个函数就行了

function MD5_Hash(const InputString: string): string

如果你要请留下Email我发给你。

来自: 99boy, 时间: 2002-12-30 15:33:00, ID: 1548997
在这里 http://www.fichtner.net/delphi/md5/ 下载

1、 MD5String、MD5File、MD5Print、MD5Match这四个函数是供调用的。其他是用来辅助这几个函数的子函数。
2、MD5String为加密字符串。
3、MD5File为加密这个文件。
4、MD5Print是将加密后的密文转换成字符串。
5、MD5Match是用来比较密文是否一致。

加密字符串aaa MD5String('aaa')
将加密后的aaa显示出来 MD5Print(MD5String('aaa'))
比较两次密文是否一致: MD5Match(MD5String('第一次明文'),MD5String('第二次输入的明文'))

如果要用这个单元,只需要在项目中添加这个文件,uses md5,就可以了
delphi 4以上版本都可以。





来自: kenxy, 时间: 2002-12-30 16:08:00, ID: 1549133
to:叮叮当当
给我一份MD5算法的Delphi源代码?
sz-sunding@163.net

来自: hq_pan, 时间: 2002-12-30 16:14:00, ID: 1549165
http://www.cityinthesky.co.uk/
上面有一个控件包下载,里面包含了加密的一系列算法。
===============================================================================
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= DCPcrypt Cryptographic Component Library v2 Beta 2 =
= Copyright (c) 1999-2002 David Barton =
= http://www.cityinthesky.co.uk/ =
= crypto@cityinthesky.co.uk =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Introduction:

DCPcrypt is a collection of cryptographic components for the Borland
Delphi(tm), C++ Builder(tm) and Kylix(tm) programming languages. The
supported versions are Delphi 4, 5 and 6, C++ Builder (3?), 4, 5, 6
and Kylix 1 (untested) and 2.

The idea behind DCPcrypt is that it should be possible to "drop in"
any algorithm implementation to replace another with minimum or no
code changes. To aid in this goal all cryptographic components are
descended from one of several base classes, TDCP_cipher for encryption
algorithms and TDCP_hash for message digest algorithms.

DCPcrypt is open source software (released under the MIT license) and
as such there is no charge for inclusion in other software. However, I
am currently a student and if you are making money from my software I
would really appreciate a donation of some sort, whether financial or
a license for the software you develop (or if anyone wants to sponsor
a Mathematical Modelling (Masters) student for their final year...).
Please note THIS IS NOT COMPULSORY IN ANY WAY. See
http://www.cityinthesky.co.uk/cryptography.html for details on
financial donations.

This software is OSI Certified Open Source Software.
OSI Certified is a certification mark of the Open Source Initiative.

If you maintain a website then a link to my page at
http://www.cityinthesky.co.uk/ would be great!



What's New:

Changes since DCPcrypt v2 Beta 1 include

* Renamed source code files for hashes and ciphers to DCPxxx.pas

* Change the format of Cipher.InitStr so that the hash algorithm
used to generate the key is explicitly specified. In order to
get the same functionality as before, use TDCP_sha1.
e.g. Cipher.InitStr('Hello World',TDCP_sha1);

* Block ciphers are now inherited from an intermediate component
that implements the block size specific chaining mode encryption
routines.

* Remove the internal component registration, it was more hassle
than it was worth. If there is a demand for this to be put back
then I might...

* Added the full range of operation modes for Haval. By changing
the defines at the top of DCPhaval.pas you can specify the
number of passes and the output hash size.

* Added the Tiger hash algorithm (192bit digest).

* Changed the name of the file containing TDCP_ripemd160 for
consistency to DCPripemd160 from DCPrmd160.

* GOST no longer appears on the component palette pending verifying
what the actual standard is (the code is still included however).

* Added the RipeMD-128 hash algorithm (128bit digest).

* Added the Serpent block cipher (AES finalist).

* Added the SHA-256,384,512 hash algorithms (256, 384, 512bit digest
respectively).

* Added CTR chaining mode to all block ciphers.



Installation:

Delphi: Open the appropriate package, DCPdelphiX.dpk where X is
your version of Delphi (either 4, 5 or 6). Then press the
install button.

C++ Builder: Create a new design time package and add all the .pas
files from the DCPcrypt2.zip archive including all those
in the Ciphers and Hashes subdirectories. Then press the
install button.

Kylix: Open the DCPkylix.dpk package and then press the install
button (note: Kylix 1 users may need to create a new
package as with C++ Builder as this is a K

来自: cola, 时间: 2002-12-30 16:20:00, ID: 1549184
delphi的MD5代码

unit md5;

// -----------------------------------------------------------------------------------------------
INTERFACE
// -----------------------------------------------------------------------------------------------

uses
Windows;

type
MD5Count = array[0..1] of DWORD;
MD5State = array[0..3] of DWORD;
MD5Block = array[0..15] of DWORD;
MD5CBits = array[0..7] of byte;
MD5Digest = array[0..15] of byte;
MD5Buffer = array[0..63] of byte;
MD5Context = record
State: MD5State;
Count: MD5Count;
Buffer: MD5Buffer;
end;

procedure MD5Init(var Context: MD5Context);
procedure MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);

function MD5String(M: string): MD5Digest;
function MD5File(N: string): MD5Digest;
function MD5Print(D: MD5Digest): string;

function MD5Match(D1, D2: MD5Digest): boolean;

// -----------------------------------------------------------------------------------------------
IMPLEMENTATION
// -----------------------------------------------------------------------------------------------

var
PADDING: MD5Buffer = (
$80, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00
);

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;
begin
Result := y xor (x or (not z));
end;

procedure rot(var x: DWORD; n: BYTE);
begin
x := (x shl n) or (x shr (32 - 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;

// -----------------------------------------------------------------------------------------------

// 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;

// Transform State according to first 64 bytes at Buffer
procedure Transform(Buffer: pointer; var State: MD5State);
var
a, b, c, d: DWORD;
Block: MD5Block;
begin
Encode(Buffer, @Block, 64);
a := State[0];
b := State[1];
c := State[2];
d := State[3];
FF (a, b, c, d, Block[ 0], 7, $d76aa478);
FF (d, a, b, c, Block[ 1], 12, $e8c7b756);
FF (c, d, a, b, Block[ 2], 17, $242070db);
FF (b, c, d, a, Block[ 3], 22, $c1bdceee);
FF (a, b, c, d, Block[ 4], 7, $f57c0faf);
FF (d, a, b, c, Block[ 5], 12, $4787c62a);
FF (c, d, a, b, Block[ 6], 17, $a8304613);
FF (b, c, d, a, Block[ 7], 22, $fd469501);
FF (a, b, c, d, Block[ 8], 7, $698098d8);
FF (d, a, b,

来自: 叮叮当当, 时间: 2002-12-30 22:52:00, ID: 1550013
To: kenxy
已发。

楼主怎么?不需要了么?

来自: kenxy, 时间: 2002-12-31 8:44:00, ID: 1550243
To:叮叮当当
非常感谢,我已收到!

来自: 叮叮当当, 时间: 2003-01-01 13:26:00, ID: 1553284
[:)]

来自: happyzxj, 时间: 2003-01-01 23:18:00, ID: 1553934
在这么多人在吹牛?
谁有DELPHI的MD5反向算法?有种的拿一个出来,这样才算有本事。

来自: 叮叮当当, 时间: 2003-01-02 16:55:00, ID: 1555821
MD5的逆向算法好像还没问世哦。[8D]

来自: doll_paul, 时间: 2003-01-02 17:01:00, ID: 1555843
To:叮叮当当,me too,EM:doll-paul@263.net

可以50给回报,谢谢了~~~~(要保证可用哦~~)

来自: happyzxj, 时间: 2003-01-02 17:26:00, ID: 1555949
有赖于数学的发展。

来自: 叮叮当当, 时间: 2003-01-04 17:26:00, ID: 1560250
To: doll_paul
已发。

来自: doll_paul, 时间: 2003-01-04 21:50:00, ID: 1560616
to 叮叮当当 ,已收到,稍后EM联系~~

测试后,给分,万分感谢!!!!!

来自: 叮叮当当, 时间: 2003-01-05 0:57:00, ID: 1560798
To: doll_paul
呵呵,不用客气,分给不给无所谓,只要交个朋友。[8D]

来自: 天空还下着沙, 时间: 2003-06-05 16:09:00, ID: 1928012
http://www.gdchunyu.com/md5.rar

来自: jiarui, 时间: 2003-06-12 13:33:00, ID: 1946180
uses
md5;

function LogEntry(Cmd, Msg: string; Dig: MD5Digest): string;
begin
Result := Format('%s(''%s'') =' + #13#10 + ' %s', [Cmd, Msg, MD5Print(Dig)]);
end;

procedure TMain.SDigestClick(Sender: TObject);
begin
with Display.Lines do begin
if Count > 0 then Add('');
Add(LogEntry('MD5String', SEdit.Text, MD5String(SEdit.Text)));
end;
end;


上面是MD5 的加密过程,不过是32bit的,怎么样才能得到16bit呢?

来自: jiarui, 时间: 2003-06-12 13:41:00, ID: 1946216
to happyzxj:
请来一份DELPHI的,谢谢!
lhb2008@168lhb.com


来自: honestman, 时间: 2003-10-20 22:30:00, ID: 2242322
测试时,发现cola的代码最后漏了“end.”。

问题讨论没有结束 ...
 
后退
顶部