你怎样定义“精确”?如果2个文件都大的话,可以考虑一次过把两个文件读入字符串或者byte数组,直接判断。如果比较大的话,应该根据实际情况分段读入判断。

解决方案 »

  1.   

    如果像楼上那样,使用MD5的话,源代码如下:Option ExplicitDim w1 As String, w2 As String, w3 As String, w4 As StringFunction MD5F(ByVal tempstr As String, ByVal w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
        MD5F = BigMod32Add(RotLeft(BigMod32Add(BigMod32Add(w, tempstr), BigMod32Add(Xin, qdata)), rots), X)
    End FunctionSub MD5F1(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
    Dim tempstr As String    tempstr = BigXOR(z, BigAND(X, BigXOR(y, z)))
        w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
    End SubSub MD5F2(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
    Dim tempstr As String    tempstr = BigXOR(y, BigAND(z, BigXOR(X, y)))
        w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
    End SubSub MD5F3(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
    Dim tempstr As String    tempstr = BigXOR(X, BigXOR(y, z))
        w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
    End SubSub MD5F4(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
    Dim tempstr As String    tempstr = BigXOR(y, BigOR(X, BigNOT(z)))
        w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
    End SubFunction MD5_Calc(ByVal hashthis As String) As String
    ReDim buf(0 To 3) As String
    ReDim Xin(0 To 15) As String
    Dim tempnum As Integer, tempnum2 As Integer, loopit As Integer, loopouter As Integer, loopinner As Integer
    Dim a As String, b As String, c As String, d As String    ' Add padding    tempnum = 8 * Len(hashthis)
        hashthis = hashthis + Chr$(128) 'Add binary 10000000
        tempnum2 = 56 - Len(hashthis) Mod 64    If tempnum2 < 0 Then
            tempnum2 = 64 + tempnum2
        End If    hashthis = hashthis + String$(tempnum2, Chr$(0))    For loopit = 1 To 8
            hashthis = hashthis + Chr$(tempnum Mod 256)
            tempnum = tempnum - tempnum Mod 256
            tempnum = tempnum / 256
        Next loopit        ' Set magic numbers
        buf(0) = "67452301"
        buf(1) = "efcdab89"
        buf(2) = "98badcfe"
        buf(3) = "10325476"        ' For each 512 bit section
        For loopouter = 0 To Len(hashthis) / 64 - 1
            a = buf(0)
            b = buf(1)
            c = buf(2)
            d = buf(3)        ' Get the 512 bits
            For loopit = 0 To 15
                Xin(loopit) = ""
                For loopinner = 1 To 4
                    Xin(loopit) = Hex$(Asc(Mid$(hashthis, 64 * loopouter + 4 * loopit + loopinner, 1))) + Xin(loopit)
                    If Len(Xin(loopit)) Mod 2 Then Xin(loopit) = "0" + Xin(loopit)
                Next loopinner
            Next loopit        ' Round 1
            MD5F1 a, b, c, d, Xin(0), "d76aa478", 7
            MD5F1 d, a, b, c, Xin(1), "e8c7b756", 12
            MD5F1 c, d, a, b, Xin(2), "242070db", 17
            MD5F1 b, c, d, a, Xin(3), "c1bdceee", 22
            MD5F1 a, b, c, d, Xin(4), "f57c0faf", 7
            MD5F1 d, a, b, c, Xin(5), "4787c62a", 12
            MD5F1 c, d, a, b, Xin(6), "a8304613", 17
            MD5F1 b, c, d, a, Xin(7), "fd469501", 22
            MD5F1 a, b, c, d, Xin(8), "698098d8", 7
            MD5F1 d, a, b, c, Xin(9), "8b44f7af", 12
            MD5F1 c, d, a, b, Xin(10), "ffff5bb1", 17
            MD5F1 b, c, d, a, Xin(11), "895cd7be", 22
            MD5F1 a, b, c, d, Xin(12), "6b901122", 7
            MD5F1 d, a, b, c, Xin(13), "fd987193", 12
            MD5F1 c, d, a, b, Xin(14), "a679438e", 17
            MD5F1 b, c, d, a, Xin(15), "49b40821", 22        ' Round 2
            MD5F2 a, b, c, d, Xin(1), "f61e2562", 5
            MD5F2 d, a, b, c, Xin(6), "c040b340", 9
            MD5F2 c, d, a, b, Xin(11), "265e5a51", 14
            MD5F2 b, c, d, a, Xin(0), "e9b6c7aa", 20
            MD5F2 a, b, c, d, Xin(5), "d62f105d", 5
            MD5F2 d, a, b, c, Xin(10), "02441453", 9
            MD5F2 c, d, a, b, Xin(15), "d8a1e681", 14
            MD5F2 b, c, d, a, Xin(4), "e7d3fbc8", 20
            MD5F2 a, b, c, d, Xin(9), "21e1cde6", 5
            MD5F2 d, a, b, c, Xin(14), "c33707d6", 9
            MD5F2 c, d, a, b, Xin(3), "f4d50d87", 14
            MD5F2 b, c, d, a, Xin(8), "455a14ed", 20
            MD5F2 a, b, c, d, Xin(13), "a9e3e905", 5
            MD5F2 d, a, b, c, Xin(2), "fcefa3f8", 9
            MD5F2 c, d, a, b, Xin(7), "676f02d9", 14
            MD5F2 b, c, d, a, Xin(12), "8d2a4c8a", 20        ' Round 3
            MD5F3 a, b, c, d, Xin(5), "fffa3942", 4
            MD5F3 d, a, b, c, Xin(8), "8771f681", 11
            MD5F3 c, d, a, b, Xin(11), "6d9d6122", 16
            MD5F3 b, c, d, a, Xin(14), "fde5380c", 23
            MD5F3 a, b, c, d, Xin(1), "a4beea44", 4
            MD5F3 d, a, b, c, Xin(4), "4bdecfa9", 11
            MD5F3 c, d, a, b, Xin(7), "f6bb4b60", 16
            MD5F3 b, c, d, a, Xin(10), "bebfbc70", 23
            MD5F3 a, b, c, d, Xin(13), "289b7ec6", 4
            MD5F3 d, a, b, c, Xin(0), "e27fa", 11
            MD5F3 c, d, a, b, Xin(3), "d4ef3085", 16
            MD5F3 b, c, d, a, Xin(6), "04881d05", 23
            MD5F3 a, b, c, d, Xin(9), "d9d4d039", 4
            MD5F3 d, a, b, c, Xin(12), "e6db99e5", 11
            MD5F3 c, d, a, b, Xin(15), "1fa27cf8", 16
            MD5F3 b, c, d, a, Xin(2), "c4ac5665", 23        ' Round 4
            MD5F4 a, b, c, d, Xin(0), "f4292244", 6
            MD5F4 d, a, b, c, Xin(7), "432aff97", 10
            MD5F4 c, d, a, b, Xin(14), "ab9423a7", 15
            MD5F4 b, c, d, a, Xin(5), "fc93a039", 21
            MD5F4 a, b, c, d, Xin(12), "655b59c3", 6
            MD5F4 d, a, b, c, Xin(3), "8f0ccc92", 10
            MD5F4 c, d, a, b, Xin(10), "ffeff47d", 15
            MD5F4 b, c, d, a, Xin(1), "85845dd1", 21
            MD5F4 a, b, c, d, Xin(8), "6fa87e4f", 6
            MD5F4 d, a, b, c, Xin(15), "fe2ce6e0", 10
            MD5F4 c, d, a, b, Xin(6), "a3014314", 15
            MD5F4 b, c, d, a, Xin(13), "4e0811a1", 21
            MD5F4 a, b, c, d, Xin(4), "f7537e82", 6
            MD5F4 d, a, b, c, Xin(11), "bd3af235", 10
            MD5F4 c, d, a, b, Xin(2), "2ad7d2bb", 15
            MD5F4 b, c, d, a, Xin(9), "eb86d391", 21        buf(0) = BigAdd(buf(0), a)
            buf(1) = BigAdd(buf(1), b)
            buf(2) = BigAdd(buf(2), c)
            buf(3) = BigAdd(buf(3), d)
        Next loopouter    ' Extract MD5Hash
        hashthis = ""
        For loopit = 0 To 3
            For loopinner = 3 To 0 Step -1
                hashthis = hashthis + Chr(Val("&H" + Mid$(buf(loopit), 1 + 2 * loopinner, 2)))
            Next loopinner
        Next loopit    ' And return it
        MD5_Calc = hashthis
    End FunctionFunction BigMod32Add(ByVal value1 As String, ByVal value2 As String) As String
        BigMod32Add = Right$(BigAdd(value1, value2), 8)
    End FunctionPublic Function BigAdd(ByVal value1 As String, ByVal value2 As String) As String
    Dim valueans As String
    Dim loopit As Integer, tempnum As Integer    tempnum = Len(value1) - Len(value2)
        If tempnum < 0 Then
            value1 = Space$(Abs(tempnum)) + value1
        ElseIf tempnum > 0 Then
            value2 = Space$(Abs(tempnum)) + value2
        End If    tempnum = 0
        For loopit = Len(value1) To 1 Step -1
            tempnum = tempnum + Val("&H" + Mid$(value1, loopit, 1)) + Val("&H" + Mid$(value2, loopit, 1))
            valueans = Hex$(tempnum Mod 16) + valueans
            tempnum = Int(tempnum / 16)
        Next loopit    If tempnum <> 0 Then
            valueans = Hex$(tempnum) + valueans
        End If    BigAdd = Right(valueans, 8)
    End FunctionPublic Function RotLeft(ByVal value1 As String, ByVal rots As Integer) As String
    Dim tempstr As String
    Dim loopit As Integer, loopinner As Integer
    Dim tempnum As Integer    rots = rots Mod 32
        
        If rots = 0 Then
            RotLeft = value1
            Exit Function
        End If    value1 = Right$(value1, 8)
        tempstr = String$(8 - Len(value1), "0") + value1
        value1 = ""    ' Convert to binary
        For loopit = 1 To 8
            tempnum = Val("&H" + Mid$(tempstr, loopit, 1))
            For loopinner = 3 To 0 Step -1
                If tempnum And 2 ^ loopinner Then
                    value1 = value1 + "1"
                Else
                    value1 = value1 + "0"
                End If
            Next loopinner
        Next loopit
        tempstr = Mid$(value1, rots + 1) + Left$(value1, rots)    ' And convert back to hex
        value1 = ""
        For loopit = 0 To 7
            tempnum = 0
            For loopinner = 0 To 3
                If Val(Mid$(tempstr, 4 * loopit + loopinner + 1, 1)) Then
                    tempnum = tempnum + 2 ^ (3 - loopinner)
                End If
            Next loopinner
            value1 = value1 + Hex$(tempnum)
        Next loopit    RotLeft = Right(value1, 8)
    End FunctionFunction BigAND(ByVal value1 As String, ByVal value2 As String) As String
    Dim valueans As String
    Dim loopit As Integer, tempnum As Integer    tempnum = Len(value1) - Len(value2)
        If tempnum < 0 Then
            value2 = Mid$(value2, Abs(tempnum) + 1)
        ElseIf tempnum > 0 Then
            value1 = Mid$(value1, tempnum + 1)
        End If    For loopit = 1 To Len(value1)
            valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) And Val("&H" + Mid$(value2, loopit, 1)))
        Next loopit    BigAND = valueans
    End FunctionFunction BigNOT(ByVal value1 As String) As String
    Dim valueans As String
    Dim loopit As Integer    value1 = Right$(value1, 8)
        value1 = String$(8 - Len(value1), "0") + value1
        For loopit = 1 To 8
            valueans = valueans + Hex$(15 Xor Val("&H" + Mid$(value1, loopit, 1)))
        Next loopit    BigNOT = valueans
    End FunctionFunction BigOR(ByVal value1 As String, ByVal value2 As String) As String
    Dim valueans As String
    Dim loopit As Integer, tempnum As Integer    tempnum = Len(value1) - Len(value2)
        If tempnum < 0 Then
            valueans = Left$(value2, Abs(tempnum))
            value2 = Mid$(value2, Abs(tempnum) + 1)
        ElseIf tempnum > 0 Then
            valueans = Left$(value1, Abs(tempnum))
            value1 = Mid$(value1, tempnum + 1)
        End If    For loopit = 1 To Len(value1)
            valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) Or Val("&H" + Mid$(value2, loopit, 1)))
        Next loopit    BigOR = valueans
    End FunctionFunction BigXOR(ByVal value1 As String, ByVal value2 As String) As String
    Dim valueans As String
    Dim loopit As Integer, tempnum As Integer    tempnum = Len(value1) - Len(value2)
        If tempnum < 0 Then
            valueans = Left$(value2, Abs(tempnum))
            value2 = Mid$(value2, Abs(tempnum) + 1)
        ElseIf tempnum > 0 Then
            valueans = Left$(value1, Abs(tempnum))
            value1 = Mid$(value1, tempnum + 1)
        End If    For loopit = 1 To Len(value1)
            valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) Xor Val("&H" + Mid$(value2, loopit, 1)))
        Next loopit    BigXOR = Right(valueans, 8)
    End Function
      

  2.   

    to enmity:
    你有没有DELPHI的源码?
      

  3.   

    to enmity
    那你有没有更好的方法??你说的速度比较慢?是什么速度慢?
      

  4.   

    to:lazecat(猫)
    没有。不过,你可以把它转为Delphi的,来来去去都是字符的运算,相信不难。如果你真的想找现成的话,建议你去www.google.com搜索:关键字:"md5"+"delphi"
      

  5.   

    to:lazecat(猫) 
    本身MD5要经过大量的运算,如果文件越大,时间消耗越多,判断速度就越慢了。
      

  6.   

    其实,比较2个文件是否不同,最简单就是用二进制方式读取文件内容到Byte数组,然后直接判断就可以了。
      

  7.   

    to enmity.
    不是吧。。我看资料上写的都是位运算啊。怎么是字符运算呢?
      

  8.   

    呵呵,对不起,打错了。VB源代码:
    'Description: Compares the content of two filesFunction CompareFiles(cFile1 As String, cFile2 As String) As Boolean    Dim IsSame%
        Dim Start&
        Dim Whole&
        Dim Part&
        Dim Buffer1$
        Dim Buffer2$
        Dim x&
            
        Open cFile1 For Binary As #1
        Open cFile2 For Binary As #2
        
        IsSame% = True
        
        If LOF(1) <> LOF(2) Then
                IsSame% = False
        Else
                Whole& = LOF(1) \ 10000         'number of whole 10,000 byte chunks
                Part& = LOF(1) Mod 10000        'remaining bytes at end of file
                Buffer1$ = String$(10000, 0)
                Buffer2$ = String$(10000, 0)
                Start& = 1
                
                For x& = 1 To Whole&            'this for-next loop will get 10,000
                    Get #1, Start&, Buffer1$      'byte chunks at a time.
                    Get #2, Start&, Buffer2$
                    If Buffer1$ <> Buffer2$ Then
                            IsSame% = False
                            Exit For
                    End If
                    Start& = Start& + 10000
                Next
                
                Buffer1$ = String$(Part&, 0)
                Buffer2$ = String$(Part&, 0)
                Get #1, Start&, Buffer1$        'get the remaining bytes at the end
                Get #2, Start&, Buffer2$        'get the remaining bytes at the end
                If Buffer1$ <> Buffer2$ Then IsSame% = False
        End If
                
        Close #1
        Close #2
        
        If IsSame% Then
            CompareFiles = True
            'MessageBox frmMain.hWnd, "两个文件是一样的!", 64 + vbSystemModal, "比较结果"
        Else
            'MessageBox frmMain.hWnd, "两个文件是不一样的!", 16 + vbSystemModal, "比较结果"
            CompareFiles = False
        End IfEnd Function
      

  9.   

    看名字,你真的很懒吗?而且,如果你想表达你是懒惰的,英文应该是:lazycat,不过,可能你觉得你现在的会比较好看 ;)
      

  10.   

    看看这里:
    http://www.fichtner.net/delphi/md5.delphi.phtml (有源代码,应该是这个了)
    http://www.fortunecity.com/skyscraper/true/882/DelphiComponents.htm
    http://www.marcocantu.com/md5/d5new.htmDelphi源代码:
    // tabs = 2
    // -----------------------------------------------------------------------------------------------
    //
    //                                 MD5 Message-Digest for Delphi 4
    //
    //                                 Delphi 4 Unit implementing the
    //                      RSA Data Security, Inc. MD5 Message-Digest Algorithm
    //
    //                          Implementation of Ronald L. Rivest's RFC 1321
    //
    //                      Copyright ?1997-1999 Medienagentur Fichtner & Meyer
    //                                  Written by Matthias Fichtner
    //
    // -----------------------------------------------------------------------------------------------
    //               See RFC 1321 for RSA Data Security's copyright and license notice!
    // -----------------------------------------------------------------------------------------------
    //
    //     14-Jun-97  mf  Implemented MD5 according to RFC 1321                           RFC 1321
    //     16-Jun-97  mf  Initial release of the compiled unit (no source code)           RFC 1321
    //     28-Feb-99  mf  Added MD5Match function for comparing two digests               RFC 1321
    //     13-Sep-99  mf  Reworked the entire unit                                        RFC 1321
    //     17-Sep-99  mf  Reworked the "Test Driver" project                              RFC 1321
    //     19-Sep-99  mf  Release of sources for MD5 unit and "Test Driver" project       RFC 1321
    //
    // -----------------------------------------------------------------------------------------------
    //                   The latest release of md5.pas will always be available from
    //                  the distribution site at: http://www.fichtner.net/delphi/md5/
    // -----------------------------------------------------------------------------------------------
    //                       Please send questions, bug reports and suggestions
    //                      regarding this code to: [email protected]
    // -----------------------------------------------------------------------------------------------
    //                        This code is provided "as is" without express or
    //                     implied warranty of any kind. Use it at your own risk.
    // -----------------------------------------------------------------------------------------------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[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.