delphi

解决方案 »

  1.   


    --------------------------------------------------------------------------------
     
    1、MD5算法是对输入的数据进行补位,使得如果数据位长度LEN对512求余的结果是448。
    即数据扩展至K*512+448位。即K*64+56个字节,K为整数。
    具体补位操作:补一个1,然后补0至满足上述要求2、补数据长度:
    用一个64位的数字表示数据的原始长度B,把B用两个32位数表示。这时,数据就被填
    补成长度为512位的倍数。3. 初始化MD5参数
    四个32位整数 (A,B,C,D) 用来计算信息摘要,初始化使用的是十六进制表示的数字A=0X01234567
    B=0X89abcdef
    C=0Xfedcba98
    D=0X765432104、处理位操作函数X,Y,Z为32位整数。
    F(X,Y,Z) = X&Y|NOT(X)&Z
    G(X,Y,Z) = X&Z|Y&not(Z)
    H(X,Y,Z) = X xor Y xor Z
    I(X,Y,Z) = Y xor (X|not(Z))5、主要变换过程:
    使用常数组T[1 ... 64], T[i]为32位整数用16进制表示,数据用16个32位的整
    数数组M[]表示。具体过程如下:/* 处理数据原文 */
    For i = 0 to N/16-1 do/*每一次,把数据原文存放在16个元素的数组X中. */
    For j = 0 to 15 do
    Set X[j] to M[i*16+j].
    end /结束对J的循环/* Save A as AA, B as BB, C as CC, and D as DD. */
    AA = A
    BB = B
    CC = C
    DD = D/* 第1轮*/
    /* 以 [abcd k s i]表示如下操作
    a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). *//* Do the following 16 operations. */
    [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
    [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
    [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
    [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]/* 第2轮* */
    /* 以 [abcd k s i]表示如下操作
    a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
    /* Do the following 16 operations. */
    [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
    [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
    [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
    [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]/* 第3轮*/
    /* 以 [abcd k s i]表示如下操作
    a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
    /* Do the following 16 operations. */
    [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
    [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
    [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
    [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]/* 第4轮*/
    /* 以 [abcd k s i]表示如下操作
    a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
    /* Do the following 16 operations. */
    [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
    [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
    [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
    [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]/* 然后进行如下操作 */
    A = A + AA
    B = B + BB
    C = C + CC
    D = D + DDend /* 结束对I的循环*/
    6、输出结果。
     
      

  2.   

    以下是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, 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;
      

  3.   


    // -----------------------------------------------------------------------------------------------// 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[I], Context.State);
    inc(I, 64);
    end;
    Index := 0;
    end else I := 0;
    CopyMemory(@Context.Buffer[Index], @Input[I], 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[I] shr 4) and $0f] + Digits[D[I] 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[I] = D2[I];
    inc(I);
    end;
    end;end.
      

  4.   

    interface
    uses Cryptcon, SysUtils{$IFDEF DELPHI}, Classes, Controls{$ENDIF}
         {$IFDEF BP7},objects{$ENDIF};Type
    ULONG32 = record
     LoWord16: WORD;
     HiWord16: WORD;
    end;PULONG32 = ^ULONG32;
    PLong = ^LongInt;hashDigest = record
      A: Longint;
      B: Longint;
      C: Longint;
      D: Longint;
    end;{hashArray}PTR_Hash = ^hashDigest;{$IFDEF DELPHI}
     TMD5 = class(TComponent)
     Private
     { Private declarations }
    {$ENDIF}{$IFDEF BP7}
     PTMD5 = ^TMD5; {For BP7 Objects}
     TMD5 = object(TObject)
     Public             {Since BP7 doesn't support Properties, we make these Public}
    {$ENDIF}  FType : TSourceType;                     {Source type, whether its a file or ByteArray, or
                                                a Pascal String}
      FInputFilePath: String;                  {Full Path to Input File}
      FInputArray: PByte;                      {Point to input array}
      FInputString: String;                    {Input String}
      FOutputDigest: PTR_Hash;                 {output MD5 Digest}
      FSourceLength: LongInt;                  {input length in BYTES}
      FActiveBlock: Array[0..15] of LongInt;   {the 64Byte block being transformed}
      FA, FB, FC, FD, FAA, FBB, FCC, FDD: LongInt;
      {FA..FDD are used during Step 4, the transform.  I made them part of the
       Object to cut down on time used to pass variables.}
      FpA, FpB, FpC, FpD: PLong;
      {FIXME! do we need these, or just use the '@' operator?}
      {Put in for readability}
      {FF, GG, HH, II are used in Step 4, the transform}
      Procedure FF(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
      Procedure GG(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
      Procedure HH(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
      Procedure II(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);{$IFDEF DELPHI}
     protected
        { Protected declarations }
    {$ENDIF}
     public
        { Public declarations }
      {Initialize is used in Step 3, this fills FA..FD with init. values
       and points FpA..FpD to FA..FD}
      Procedure MD5_Initialize;
      {this is where all the magic happens}
      Procedure MD5_Transform;
      Procedure MD5_Finish;
      Procedure MD5_Hash_Bytes;
    {  Procedure MD5_Hash_String;(Pascal Style strings???)}
      Procedure MD5_Hash_File;
      {This procedure sends the data 64Bytes at a time to MD5_Transform}
      Procedure MD5_Hash;
    {$IFDEF DELPHI}
      Property pInputArray: PByte read FInputArray write FInputArray;
      Property pOutputArray: PTR_Hash read FOutputDigest write FOutputDigest;{!!See FOutputArray}
     Published
      Property InputType: TSourceType read FType write FType;
      Property InputFilePath: String read FInputFilePath write FInputFilePath;
      Property InputString: String read FInputString write FInputString;
      Property InputLength: LongInt read FSourceLength write FSourceLength;
    {$ENDIF}
    end;{TMD5}{$IFDEF DELPHI}
     procedure Register;{register the component to the Delphi toolbar}
    {$ENDIF}Const
    {Constants for MD5Transform routine.}
     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;
      

  5.   

    implementation{This will only work on an intel}
    {$IFDEF i286}
    Function ROL(A: Longint; Amount: BYTE): Longint;NEAR;
    begin
      inline(
      $8A/$4E/$04/        { mov cl,[bp+4]  }
      $66/$8B/$46/$06/    { mov eax,[bp+6] }
      $66/$D3/$C0/        { rol eax,cl     }
      $66/$89/$46/$FC     { mov [bp-4],eax }
      );
    end;
    {$ENDIF}{$IFDEF i386}
    Function ROL(A: Longint; Amount: BYTE): Longint; Assembler;
    asm
     mov cl, Amount
     rol eax, cl
    end;
    {$ENDIF}{$IFDEF DELPHI}
    procedure Register;
      {Registers the Component to the toobar, on the tab named 'Crypto'}
      {Now all a Delphi programmer needs to do is drag n drop to have
       Blowfish encryption}
    begin
      RegisterComponents('Crypto', [TMD5]);
    end;
    {$ENDIF}
    Procedure TMD5.MD5_Initialize;
    var
     a, b, c, d: LongInt;
    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;{MD5_Initialize}Procedure TMD5.FF(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
    {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
    }
    var
     Fret: LongInt;
    begin
     Fret := ((PLong(b)^) And (PLong(c)^)) Or ((Not(PLong(b)^)) And (PLong(d)^));
     PLong(a)^ := PLong(a)^ + Fret + PLong(x)^ + ac;
     {NOW DO THE ROTATE LEFT}
     LongInt(a^):= ROL(LongInt(a^), s);
     {LongInt(a^):= ( LongInt(a^) SHL s) Or (LongInt(a^) SHR (32-(s)) );}
     Inc(PLong(a)^, PLong(b)^);
    end;{FF}Procedure TMD5.GG(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
    {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
    }
    var
     Gret: LongInt;
    begin
     Gret := (PLong(b)^ And PLong(d)^) Or ( PLong(c)^ And (Not PLong(d)^));
     PLong(a)^ := PLong(a)^ + Gret + PLong(x)^ + ac;
     LongInt(a^):= ROL(LongInt(a^), s);
     {LongInt(a^):= ( LongInt(a^) SHL s) Or (LongInt(a^) SHR (32-(s)) );}
     Inc(PLong(a)^, PLong(b)^);
    end;{GG}Procedure TMD5.HH(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
    {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
    }
    var
     Hret: LongInt;
    begin
     Hret := PLong(b)^ Xor PLong(c)^ Xor PLong(d)^;
     PLong(a)^ := PLong(a)^ + Hret + PLong(x)^ + ac;
     LongInt(a^):= ROL(LongInt(a^), s);
     {LongInt(a^):= ( LongInt(a^) SHL s) Or (LongInt(a^) SHR (32-(s)) );}
     PLong(a)^ := PLong(b)^ + PLong(a)^;
    end;{HH}Procedure TMD5.II(a, b, c, d, x: Pointer; s: BYTE; ac: Longint);
    {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))
    }
    var
     Iret: LongInt;
    begin
     Iret := (PLong(c)^ Xor (PLong(b)^ Or (Not PLong(d)^)));
     PLong(a)^ := PLong(a)^ + Iret + PLong(x)^ + ac;
     LongInt(a^):= ROL(PLong(a)^, s );
    { LongInt(a^):= ( LongInt(a^) SHL s) Or (LongInt(a^) SHR (32-(s)) );}
     PLong(a)^ := PLong(b)^ + PLong(a)^;
    end;{II}Procedure TMD5.MD5_Transform;
    {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.
    }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,  $2441453); { 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,  $4881d05); { 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 }
      

  6.   


      Inc(FA, FAA);
      Inc(FB, FBB);
      Inc(FC, FCC);
      Inc(FD, FDD);
      { Zeroize sensitive information}
      FillChar(FActiveBlock, SizeOf(FActiveBlock), #0);
    end;{TMD5.MD5_Transform}
    Procedure TMD5.MD5_Hash;
    var
     pStr: PChar;
    begin
      MD5_Initialize;
      case FType of
       SourceFile:
       begin
        MD5_Hash_File;
       end;{SourceFile}
       SourceByteArray:
       begin
        MD5_Hash_Bytes;
       end;{SourceByteArray}
       SourceString:
       begin
        {Convert Pascal String to Byte Array}
     {$IFDEF DELPHI}
        pStr := StrAlloc(Length(FInputString) + 1);
        try {protect dyanmic memory allocation}
        StrPCopy(pStr, FInputString);
     {$ENDIF}
     {$IFDEF BP7}
        GetMem(pStr, Length(FInputString));
        Move(FInputString[1],pStr^, Length(FInputString));
     {$ENDIF}
        FSourceLength := Length(FInputString);
        FInputArray := Pointer(pStr);
        MD5_Hash_Bytes;
     {$IFDEF DELPHI}
        finally
         StrDispose(pStr);
        end;
     {$ENDIF}
     {$IFDEF BP7}
        FreeMem(pStr,Length(FInputString));
     {$ENDIF}
       end;{SourceString}
      end;{case}
      MD5_Finish;
    end;{TMD5.MD5_Hash}Procedure TMD5.MD5_Hash_Bytes;
    var
      Buffer: array[0..4159] of Byte;
      Count64: Comp;
      index: longInt;
    begin
      Move(FInputArray^, Buffer, FSourceLength);
      Count64 := FSourceLength * 8;     {Save the Length(in bits) before padding}
      Buffer[FSourceLength] := $80;     {Must always pad with at least a '1'}
      inc(FSourceLength);  while (FSourceLength mod 64)<>56 do begin
       Buffer[FSourceLength] := 0;
       Inc(FSourceLength);
      end;
      Move(Count64,Buffer[FSourceLength],SizeOf(Count64){This better be 64bits});
      index := 0;
      Inc(FSourceLength, 8);
      repeat
        Move(Buffer[Index], FActiveBlock, 64);
        {Flip bytes here on Mac??}
        MD5_Transform;
        Inc(Index,64);
      until Index = FSourceLength;
    end;{TMD5.Hash_Bytes}Procedure TMD5.MD5_Hash_File;
    var
      Buffer:array[0..4159] of BYTE;
      InputFile: File;
      Count64: Comp;
      DoneFile : Boolean;
      Index: LongInt;
      NumRead: {$IFDEF DELPHI32}integer {$ELSE}WORD{$ENDIF};
    begin
    DoneFile := False;
    {$IFDEF DELPHI}
     AssignFile(InputFile, FInputFilePath);
    {$ENDIF}
    {$IFDEF BP7}
     Assign(InputFile, FInputFilePath);
    {$ENDIF}Reset(InputFile, 1);
    Count64 := 0;
    repeat
        BlockRead(InputFile,Buffer,4096,NumRead);
        Count64 := Count64 + NumRead;
        if NumRead<>4096 {reached end of file}
          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);
         {Flip bytes here on a Mac(I think)}     MD5_Transform;
         Inc(Index,64);
        until Index = NumRead;
      until DoneFile;
    {$IFDEF DELPHI}
      CloseFile(InputFile);
    {$ENDIF}
    {$IFDEF BP7}
      Close(InputFile);
    {$ENDIF}
    end;{TMD5.MD5_Hash_File}
    Procedure TMD5.MD5_Finish;
    begin
     FOutputDigest^.A := LongInt(FpA^);
     FOutputDigest^.B := LongInt(FpB^);
     FOutputDigest^.C := LongInt(FpC^);
     FOutputDigest^.D := LongInt(FpD^);
    end;
    end.
      

  7.   

    更多内容到这里找:
    http://www.fichtner.net/delphi/md5.delphi.phtml