谁有MD5的算法???(50分)

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

cq_139

Unregistered / Unconfirmed
GUEST, unregistred user!
现在本人急需MD5算法C++Builder?
 
难道没有用C++Builder写过吗?
 
把这个下面这段代码保存为:MD5.pas
在BCB加到当前工程中,单独编译MD5.pas,将产生一个MD5.hpp;
#include "md5.hpp"
THashDigest res;
TMD5 *md5 = new TMD5;
md5->InputType = itString;
md5->InputString = str;
md5->POutputArray = &res;
md5->HashCalc();
delete md5;
结果在res内。
//------------------------------------------------------------------------------
unit MD5;
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) <> 56do
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
do
neFile: Boolean;
InputFile: file;
Count64: Comp;
Index, NumRead: Integer;
Buffer: array[0..4159] of Byte;
begin
do
neFile := 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) <> 56do
begin
Buffer[NumRead] := 0;
Inc(NumRead);
end;
Count64 := Count64 * 8;
Move(Count64, Buffer[NumRead], 8);
Inc(NumRead, 8);
do
neFile := True;
end;
Index := 0;
repeat
Move(Buffer[Index], FActiveBlock, 64);
HashTransform;
Inc(Index, 64);
until Index = NumRead;
untildo
neFile;
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.
 
《应用密码学》(外国人写的,记不清叫什么名字了)的附录里就有若干算法的代码,里面连DES的都有,MD5的估计也是有的,但代码都是印刷出来的,不知道是否完全正确。
如果你只想用用,那么可以研究一下CryptoAPI或者干脆用CAPICOM组件好了。
http://www.microsoft.com/downloads/details.aspx?FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6&amp;displaylang=en
 
apw 果然经典!
发分落!
 
后退
顶部