请教大虾,谁能给我一个32位的md5加密算法

解决方案 »

  1.   

    Attribute VB_Name = "mMD5"' MODULE:       CMD5
    '*******************************************************************************
    Option ExplicitPublic Const BITS_TO_A_BYTE  As Long = 8
    Public Const BYTES_TO_A_WORD As Long = 4
    Public Const BITS_TO_A_WORD  As Long = BYTES_TO_A_WORD * BITS_TO_A_BYTEPublic m_lOnBits(0 To 30) As Long
    Public m_l2Power(0 To 30) As Long'*******************************************************************************
    ' Class_Initialize (SUB)
    '
    ' DESCRIPTION:
    ' We will usually get quicker results by preparing arrays of bit patterns and
    ' powers of 2 ahead of time instead of calculating them every time, unless of
    ' course the methods are only ever getting called once per instantiation of the
    ' class.
    '*******************************************************************************
    Public Sub Initialize()
        ' Could have done this with a loop calculating each value, but simply
        ' assigning the values is quicker - BITS SET FROM RIGHT
        m_lOnBits(0) = 1            ' 00000000000000000000000000000001
        m_lOnBits(1) = 3            ' 00000000000000000000000000000011
        m_lOnBits(2) = 7            ' 00000000000000000000000000000111
        m_lOnBits(3) = 15           ' 00000000000000000000000000001111
        m_lOnBits(4) = 31           ' 00000000000000000000000000011111
        m_lOnBits(5) = 63           ' 00000000000000000000000000111111
        m_lOnBits(6) = 127          ' 00000000000000000000000001111111
        m_lOnBits(7) = 255          ' 00000000000000000000000011111111
        m_lOnBits(8) = 511          ' 00000000000000000000000111111111
        m_lOnBits(9) = 1023         ' 00000000000000000000001111111111
        m_lOnBits(10) = 2047        ' 00000000000000000000011111111111
        m_lOnBits(11) = 4095        ' 00000000000000000000111111111111
        m_lOnBits(12) = 8191        ' 00000000000000000001111111111111
        m_lOnBits(13) = 16383       ' 00000000000000000011111111111111
        m_lOnBits(14) = 32767       ' 00000000000000000111111111111111
        m_lOnBits(15) = 65535       ' 00000000000000001111111111111111
        m_lOnBits(16) = 131071      ' 00000000000000011111111111111111
        m_lOnBits(17) = 262143      ' 00000000000000111111111111111111
        m_lOnBits(18) = 524287      ' 00000000000001111111111111111111
        m_lOnBits(19) = 1048575     ' 00000000000011111111111111111111
        m_lOnBits(20) = 2097151     ' 00000000000111111111111111111111
        m_lOnBits(21) = 4194303     ' 00000000001111111111111111111111
        m_lOnBits(22) = 8388607     ' 00000000011111111111111111111111
        m_lOnBits(23) = 16777215    ' 00000000111111111111111111111111
        m_lOnBits(24) = 33554431    ' 00000001111111111111111111111111
        m_lOnBits(25) = 67108863    ' 00000011111111111111111111111111
        m_lOnBits(26) = 134217727   ' 00000111111111111111111111111111
        m_lOnBits(27) = 268435455   ' 00001111111111111111111111111111
        m_lOnBits(28) = 536870911   ' 00011111111111111111111111111111
        m_lOnBits(29) = 1073741823  ' 00111111111111111111111111111111
        m_lOnBits(30) = 2147483647  ' 01111111111111111111111111111111
        
        ' Could have done this with a loop calculating each value, but simply
        ' assigning the values is quicker - POWERS OF 2
        m_l2Power(0) = 1            ' 00000000000000000000000000000001
        m_l2Power(1) = 2            ' 00000000000000000000000000000010
        m_l2Power(2) = 4            ' 00000000000000000000000000000100
        m_l2Power(3) = 8            ' 00000000000000000000000000001000
        m_l2Power(4) = 16           ' 00000000000000000000000000010000
        m_l2Power(5) = 32           ' 00000000000000000000000000100000
        m_l2Power(6) = 64           ' 00000000000000000000000001000000
        m_l2Power(7) = 128          ' 00000000000000000000000010000000
        m_l2Power(8) = 256          ' 00000000000000000000000100000000
        m_l2Power(9) = 512          ' 00000000000000000000001000000000
        m_l2Power(10) = 1024        ' 00000000000000000000010000000000
        m_l2Power(11) = 2048        ' 00000000000000000000100000000000
        m_l2Power(12) = 4096        ' 00000000000000000001000000000000
        m_l2Power(13) = 8192        ' 00000000000000000010000000000000
        m_l2Power(14) = 16384       ' 00000000000000000100000000000000
        m_l2Power(15) = 32768       ' 00000000000000001000000000000000
        m_l2Power(16) = 65536       ' 00000000000000010000000000000000
        m_l2Power(17) = 131072      ' 00000000000000100000000000000000
        m_l2Power(18) = 262144      ' 00000000000001000000000000000000
        m_l2Power(19) = 524288      ' 00000000000010000000000000000000
        m_l2Power(20) = 1048576     ' 00000000000100000000000000000000
        m_l2Power(21) = 2097152     ' 00000000001000000000000000000000
        m_l2Power(22) = 4194304     ' 00000000010000000000000000000000
        m_l2Power(23) = 8388608     ' 00000000100000000000000000000000
        m_l2Power(24) = 16777216    ' 00000001000000000000000000000000
        m_l2Power(25) = 33554432    ' 00000010000000000000000000000000
        m_l2Power(26) = 67108864    ' 00000100000000000000000000000000
        m_l2Power(27) = 134217728   ' 00001000000000000000000000000000
        m_l2Power(28) = 268435456   ' 00010000000000000000000000000000
        m_l2Power(29) = 536870912   ' 00100000000000000000000000000000
        m_l2Power(30) = 1073741824  ' 01000000000000000000000000000000
    End Sub'*******************************************************************************
    ' LShift (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lValue     - Long    - The value to be shifted
    ' (In) - iShiftBits - Integer - The number of bits to shift the value by
    '
    ' RETURN VALUE:
    ' Long - The shifted long integer
    '
    ' DESCRIPTION:
    ' A left shift takes all the set binary bits and moves them left, in-filling
    ' with zeros in the vacated bits on the right. This function is equivalent to
    ' the << operator in Java and C++
    '*******************************************************************************
    Private Function LShift(ByVal lValue As Long, _
                            ByVal iShiftBits As Integer) As Long
        ' NOTE: If you can guarantee that the Shift parameter will be in the
        ' range 1 to 30 you can safely strip of this first nested if structure for
        ' speed.
        '
        ' A shift of zero is no shift at all.
        If iShiftBits = 0 Then
            LShift = lValue
            Exit Function
            
        ' A shift of 31 will result in the right most bit becoming the left most
        ' bit and all other bits being cleared
        ElseIf iShiftBits = 31 Then
            If lValue And 1 Then
                LShift = &H80000000
            Else
                LShift = 0
            End If
            Exit Function
            
        ' A shift of less than zero or more than 31 is undefined
        ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
            Err.Raise 6
        End If
        
        ' If the left most bit that remains will end up in the negative bit
        ' position (&H80000000) we would end up with an overflow if we took the
        ' standard route. We need to strip the left most bit and add it back
        ' afterwards.
        If (lValue And m_l2Power(31 - iShiftBits)) Then
        
            ' (Value And OnBits(31 - (Shift + 1))) chops off the left most bits that
            ' we are shifting into, but also the left most bit we still want as this
            ' is going to end up in the negative bit er position (&H80000000).
            ' After the multiplication/shift we Or the result with &H80000000 to
            ' turn the negative bit on.
            LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1))) * _
                m_l2Power(iShiftBits)) Or &H80000000
        
        Else
        
            ' (Value And OnBits(31-Shift)) chops off the left most bits that we are
            ' shifting into so we do not get an overflow error when we do the
            ' multiplication/shift
            LShift = ((lValue And m_lOnBits(31 - iShiftBits)) * _
                m_l2Power(iShiftBits))
            
        End If
    End Function
      

  2.   


    '*******************************************************************************
    ' RShift (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lValue     - Long    - The value to be shifted
    ' (In) - iShiftBits - Integer - The number of bits to shift the value by
    '
    ' RETURN VALUE:
    ' Long - The shifted long integer
    '
    ' DESCRIPTION:
    ' The right shift of an unsigned long integer involves shifting all the set bits
    ' to the right and in-filling on the left with zeros. This function is
    ' equivalent to the >>> operator in Java or the >> operator in C++ when used on
    ' an unsigned long.
    '*******************************************************************************
    Private Function RShift(ByVal lValue As Long, _
                            ByVal iShiftBits As Integer) As Long
        
        ' NOTE: If you can guarantee that the Shift parameter will be in the
        ' range 1 to 30 you can safely strip of this first nested if structure for
        ' speed.
        '
        ' A shift of zero is no shift at all
        If iShiftBits = 0 Then
            RShift = lValue
            Exit Function
            
        ' A shift of 31 will clear all bits and move the left most bit to the right
        ' most bit position
        ElseIf iShiftBits = 31 Then
            If lValue And &H80000000 Then
                RShift = 1
            Else
                RShift = 0
            End If
            Exit Function
            
        ' A shift of less than zero or more than 31 is undefined
        ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
            Err.Raise 6
        End If
        
        ' We do not care about the top most bit or the final bit, the top most bit
        ' will be taken into account in the next stage, the final bit (whether it
        ' is an odd number or not) is being shifted into, so we do not give a jot
        ' about it
        RShift = (lValue And &H7FFFFFFE) \ m_l2Power(iShiftBits)
        
        ' If the top most bit (&H80000000) was set we need to do things differently
        ' as in a normal VB signed long integer the top most bit is used to indicate
        ' the sign of the number, when it is set it is a negative number, so just
        ' deviding by a factor of 2 as above would not work.
        ' NOTE: (lValue And  &H80000000) is equivalent to (lValue < 0), you could
        ' get a very marginal speed improvement by changing the test to (lValue < 0)
        If (lValue And &H80000000) Then
            ' We take the value computed so far, and then add the left most negative
            ' bit after it has been shifted to the right the appropriate number of
            ' places
            RShift = (RShift Or (&H40000000 \ m_l2Power(iShiftBits - 1)))
        End If
    End Function'*******************************************************************************
    ' RShiftSigned (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lValue     - Long    -
    ' (In) - iShiftBits - Integer -
    '
    ' RETURN VALUE:
    ' Long -
    '
    ' DESCRIPTION:
    ' The right shift of a signed long integer involves shifting all the set bits to
    ' the right and in-filling on the left with the sign bit (0 if positive, 1 if
    ' negative. This function is equivalent to the >> operator in Java or the >>
    ' operator in C++ when used on a signed long integer. Not used in this class,
    ' but included for completeness.
    '*******************************************************************************
    Private Function RShiftSigned(ByVal lValue As Long, _
                                  ByVal iShiftBits As Integer) As Long
        
        ' NOTE: If you can guarantee that the Shift parameter will be in the
        ' range 1 to 30 you can safely strip of this first nested if structure for
        ' speed.
        '
        ' A shift of zero is no shift at all
        If iShiftBits = 0 Then
            RShiftSigned = lValue
            Exit Function
        
        ' A shift of 31 will clear all bits if the left most bit was zero, and will
        ' set all bits if the left most bit was 1 (a negative indicator)
        ElseIf iShiftBits = 31 Then
            
            ' NOTE: (lValue And  &H80000000) is equivalent to (lValue < 0), you
            ' could get a very marginal speed improvement by changing the test to
            ' (lValue < 0)
            If (lValue And &H80000000) Then
                RShiftSigned = -1
            Else
                RShiftSigned = 0
            End If
            Exit Function
        
        ' A shift of less than zero or more than 31 is undefined
        ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
            Err.Raise 6
        End If
        
        ' We get the same result by dividing by the appropriate power of 2 and
        ' rounding in the negative direction
        RShiftSigned = Int(lValue / m_l2Power(iShiftBits))
    End Function'*******************************************************************************
    ' RotateLeft (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lValue     - Long    - Value to act on
    ' (In) - iShiftBits - Integer - Bits to move by
    '
    ' RETURN VALUE:
    ' Long - Result
    '
    ' DESCRIPTION:
    ' Rotates the bits in a long integer to the left, those bits falling off the
    ' left edge are put back on the right edge
    '*******************************************************************************
    Private Function RotateLeft(ByVal lValue As Long, _
                                ByVal iShiftBits As Integer) As Long
        RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits))
    End Function'*******************************************************************************
    ' AddUnsigned (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lX - Long - First value
    ' (In) - lY - Long - Second value
    '
    ' RETURN VALUE:
    ' Long - Result
    '
    ' DESCRIPTION:
    ' Adds two potentially large unsigned numbers without overflowing
    '*******************************************************************************
      

  3.   

    Private Function AddUnsigned(ByVal lX As Long, _
                                 ByVal lY As Long) As Long
        Dim lX4     As Long
        Dim lY4     As Long
        Dim lX8     As Long
        Dim lY8     As Long
        Dim lResult As Long
     
        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'*******************************************************************************
    ' F (FUNCTION)
    '
    ' DESCRIPTION:
    ' MD5's F function
    '*******************************************************************************
    Private Function F(ByVal x As Long, _
                       ByVal y As Long, _
                       ByVal z As Long) As Long
        F = (x And y) Or ((Not x) And z)
    End Function'*******************************************************************************
    ' G (FUNCTION)
    '
    ' DESCRIPTION:
    ' MD5's G function
    '*******************************************************************************
    Private Function G(ByVal x As Long, _
                       ByVal y As Long, _
                       ByVal z As Long) As Long
        G = (x And z) Or (y And (Not z))
    End Function'*******************************************************************************
    ' H (FUNCTION)
    '
    ' DESCRIPTION:
    ' MD5's H function
    '*******************************************************************************
    Private Function H(ByVal x As Long, _
                       ByVal y As Long, _
                       ByVal z As Long) As Long
        H = (x Xor y Xor z)
    End Function'*******************************************************************************
    ' I (FUNCTION)
    '
    ' DESCRIPTION:
    ' MD5's I function
    '*******************************************************************************
    Private Function I(ByVal x As Long, _
                       ByVal y As Long, _
                       ByVal z As Long) As Long
        I = (y Xor (x Or (Not z)))
    End Function'*******************************************************************************
    ' FF (SUB)
    '
    ' DESCRIPTION:
    ' MD5's FF procedure
    '*******************************************************************************
    Private Sub FF(a As Long, _
                   ByVal b As Long, _
                   ByVal c As Long, _
                   ByVal d As Long, _
                   ByVal x As Long, _
                   ByVal s As Long, _
                   ByVal ac As Long)
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac))
        a = RotateLeft(a, s)
        a = AddUnsigned(a, b)
    End Sub'*******************************************************************************
    ' GG (SUB)
    '
    ' DESCRIPTION:
    ' MD5's GG procedure
    '*******************************************************************************
    Private Sub GG(a As Long, _
                   ByVal b As Long, _
                   ByVal c As Long, _
                   ByVal d As Long, _
                   ByVal x As Long, _
                   ByVal s As Long, _
                   ByVal ac As Long)
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac))
        a = RotateLeft(a, s)
        a = AddUnsigned(a, b)
    End Sub'*******************************************************************************
    ' HH (SUB)
    '
    ' DESCRIPTION:
    ' MD5's HH procedure
    '*******************************************************************************
    Private Sub HH(a As Long, _
                   ByVal b As Long, _
                   ByVal c As Long, _
                   ByVal d As Long, _
                   ByVal x As Long, _
                   ByVal s As Long, _
                   ByVal ac As Long)
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac))
        a = RotateLeft(a, s)
        a = AddUnsigned(a, b)
    End Sub'*******************************************************************************
    ' II (SUB)
    '
    ' DESCRIPTION:
    ' MD5's II procedure
    '*******************************************************************************
    Private Sub II(a As Long, _
                   ByVal b As Long, _
                   ByVal c As Long, _
                   ByVal d As Long, _
                   ByVal x As Long, _
                   ByVal s As Long, _
                   ByVal ac As Long)
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac))
        a = RotateLeft(a, s)
        a = AddUnsigned(a, b)
    End Sub'*******************************************************************************
    ' ConvertToWordArray (FUNCTION)
    '
    ' PARAMETERS:
    ' (In/Out) - sMessage - String - String message
    '
    ' RETURN VALUE:
    ' Long() - Converted message as long array
    '
    ' DESCRIPTION:
    ' Takes the string message and puts it in a long array with padding according to
    ' the MD5 rules. Note we are using only the first byte of each character with
    ' the AscB function, this may well mess up in unicode/dbcs situations where you
    ' are comparing what was generated on two different PCs with different
    ' character sets.
    '*******************************************************************************
      

  4.   

    Private Function ConvertToWordArray(sMessage As String) As Long()
        Dim lMessageLength  As Long
        Dim lNumberOfWords  As Long
        Dim lWordArray()    As Long
        Dim lBytePosition   As Long
        Dim lByteCount      As Long
        Dim lWordCount      As Long
        Dim lChar           As Long
        
        Const MODULUS_BITS      As Long = 512
        Const CONGRUENT_BITS    As Long = 448
        
        lMessageLength = Len(sMessage)
        
        ' Get padded number of words. Message needs to be congruent to 448 bits,
        ' modulo 512 bits. If it is exactly congruent to 448 bits, modulo 512 bits
        ' it must still have another 512 bits added. 512 bits = 64 bytes
        ' (or 16 * 4 byte words), 448 bits = 56 bytes. This means lMessageSize must
        ' be a multiple of 16 (i.e. 16 * 4 (bytes) * 8 (bits))
        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)
        
        ' Combine each block of 4 bytes (ascii code of character) into one long
        ' value and store in the message. The high-order (most significant) bit of
        ' each byte is listed first. However, the low-order (least significant) byte
        ' is given first in each word.
        lBytePosition = 0
        lByteCount = 0
        Do Until lByteCount >= lMessageLength
            ' Each word is 4 bytes
            lWordCount = lByteCount \ BYTES_TO_A_WORD
                    
            ' The bytes are put in the word from the right most edge
            lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
            lChar = AscB(Mid(sMessage, lByteCount + 1, 1))
            lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(lChar, lBytePosition)
            lByteCount = lByteCount + 1
        Loop    ' Terminate according to MD5 rules with a 1 bit, zeros and the length in
        ' bits stored in the last two words
        lWordCount = lByteCount \ BYTES_TO_A_WORD
        lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE    ' Add a terminating 1 bit, all the rest of the bits to the end of the
        ' word array will default to zero
        lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80, lBytePosition)    ' We put the length of the message in bits into the last two words, to get
        ' the length in bits we need to multiply by 8 (or left shift 3). This left
        ' shifted value is put in the first word. Any bits shifted off the left edge
        ' need to be put in the second word, we can work out which bits by shifting
        ' right the length by 29 bits.
        lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3)
        lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29)
        
        ConvertToWordArray = lWordArray
    End Function'*******************************************************************************
    ' WordToHex (FUNCTION)
    '
    ' PARAMETERS:
    ' (In) - lValue - Long - Long value to convert
    '
    ' RETURN VALUE:
    ' String - Hex value to return
    '
    ' DESCRIPTION:
    ' Takes a long integer and due to the bytes reverse order it extracts the
    ' individual bytes and converts them to hex appending them for an overall hex
    ' value
    '*******************************************************************************
    Private Function WordToHex(ByVal lValue As Long) As String
        Dim lByte As Long
        Dim lCount As Long
        
        For lCount = 0 To 3
            lByte = RShift(lValue, lCount * BITS_TO_A_BYTE) And _
                m_lOnBits(BITS_TO_A_BYTE - 1)
            WordToHex = WordToHex & Right("0" & Hex(lByte), 2)
        Next
    End Function'*******************************************************************************
    ' MD5 (FUNCTION)
    '
    ' PARAMETERS:
    ' (In/Out) - sMessage - String - String to be digested
    '
    ' RETURN VALUE:
    ' String - The MD5 digest
    '
    ' DESCRIPTION:
    ' This function takes a string message and generates an MD5 digest for it.
    ' sMessage can be up to the VB string length limit of 2^31 (approx. 2 billion)
    ' characters.
    '
    ' NOTE: Due to the way in which the string is processed the routine assumes a
    ' single byte character set. VB passes unicode (2-byte) character strings, the
    ' ConvertToWordArray function uses on the first byte for each character. This
    ' has been done this way for ease of use, to make the routine truely portable
    ' you could accept a byte array instead, it would then be up to the calling
    ' routine to make sure that the byte array is generated from their string in
    ' a manner consistent with the string type.
    '*******************************************************************************
      

  5.   

    Public Function MD5(sMessage As String) As String
        Dim x() As Long
        Dim k   As Long
        Dim AA  As Long
        Dim BB  As Long
        Dim CC  As Long
        Dim DD  As Long
        Dim a   As Long
        Dim b   As Long
        Dim c   As Long
        Dim d   As Long
        
        Const S11 As Long = 7
        Const S12 As Long = 12
        Const S13 As Long = 17
        Const S14 As Long = 22
        Const S21 As Long = 5
        Const S22 As Long = 9
        Const S23 As Long = 14
        Const S24 As Long = 20
        Const S31 As Long = 4
        Const S32 As Long = 11
        Const S33 As Long = 16
        Const S34 As Long = 23
        Const S41 As Long = 6
        Const S42 As Long = 10
        Const S43 As Long = 15
        Const S44 As Long = 21    ' Steps 1 and 2.  Append padding bits and length and convert to words
        x = ConvertToWordArray(sMessage)
        
        ' Step 3.  Initialise
        a = &H67452301
        b = &HEFCDAB89
        c = &H98BADCFE
        d = &H10325476    ' Step 4.  Process the message in 16-word blocks
        For k = 0 To UBound(x) Step 16
            AA = a
            BB = b
            CC = c
            DD = d
        
            ' The hex number on the end of each of the following procedure calls is
            ' an element from the 64 element table constructed with
            ' T(i) = Int(4294967296 * Abs(Sin(i))) where i is 1 to 64.
            '
            ' However, for speed we don't want to calculate the value every time.
            FF a, b, c, d, x(k + 0), S11, &HD76AA478
            FF d, a, b, c, x(k + 1), S12, &HE8C7B756
            FF c, d, a, b, x(k + 2), S13, &H242070DB
            FF b, c, d, a, x(k + 3), S14, &HC1BDCEEE
            FF a, b, c, d, x(k + 4), S11, &HF57C0FAF
            FF d, a, b, c, x(k + 5), S12, &H4787C62A
            FF c, d, a, b, x(k + 6), S13, &HA8304613
            FF b, c, d, a, x(k + 7), S14, &HFD469501
            FF a, b, c, d, x(k + 8), S11, &H698098D8
            FF d, a, b, c, x(k + 9), S12, &H8B44F7AF
            FF c, d, a, b, x(k + 10), S13, &HFFFF5BB1
            FF b, c, d, a, x(k + 11), S14, &H895CD7BE
            FF a, b, c, d, x(k + 12), S11, &H6B901122
            FF d, a, b, c, x(k + 13), S12, &HFD987193
            FF c, d, a, b, x(k + 14), S13, &HA679438E
            FF b, c, d, a, x(k + 15), S14, &H49B40821
        
            GG a, b, c, d, x(k + 1), S21, &HF61E2562
            GG d, a, b, c, x(k + 6), S22, &HC040B340
            GG c, d, a, b, x(k + 11), S23, &H265E5A51
            GG b, c, d, a, x(k + 0), S24, &HE9B6C7AA
            GG a, b, c, d, x(k + 5), S21, &HD62F105D
            GG d, a, b, c, x(k + 10), S22, &H2441453
            GG c, d, a, b, x(k + 15), S23, &HD8A1E681
            GG b, c, d, a, x(k + 4), S24, &HE7D3FBC8
            GG a, b, c, d, x(k + 9), S21, &H21E1CDE6
            GG d, a, b, c, x(k + 14), S22, &HC33707D6
            GG c, d, a, b, x(k + 3), S23, &HF4D50D87
            GG b, c, d, a, x(k + 8), S24, &H455A14ED
            GG a, b, c, d, x(k + 13), S21, &HA9E3E905
            GG d, a, b, c, x(k + 2), S22, &HFCEFA3F8
            GG c, d, a, b, x(k + 7), S23, &H676F02D9
            GG b, c, d, a, x(k + 12), S24, &H8D2A4C8A
                
            HH a, b, c, d, x(k + 5), S31, &HFFFA3942
            HH d, a, b, c, x(k + 8), S32, &H8771F681
            HH c, d, a, b, x(k + 11), S33, &H6D9D6122
            HH b, c, d, a, x(k + 14), S34, &HFDE5380C
            HH a, b, c, d, x(k + 1), S31, &HA4BEEA44
            HH d, a, b, c, x(k + 4), S32, &H4BDECFA9
            HH c, d, a, b, x(k + 7), S33, &HF6BB4B60
            HH b, c, d, a, x(k + 10), S34, &HBEBFBC70
            HH a, b, c, d, x(k + 13), S31, &H289B7EC6
            HH d, a, b, c, x(k + 0), S32, &HEAA127FA
            HH c, d, a, b, x(k + 3), S33, &HD4EF3085
            HH b, c, d, a, x(k + 6), S34, &H4881D05
            HH a, b, c, d, x(k + 9), S31, &HD9D4D039
            HH d, a, b, c, x(k + 12), S32, &HE6DB99E5
            HH c, d, a, b, x(k + 15), S33, &H1FA27CF8
            HH b, c, d, a, x(k + 2), S34, &HC4AC5665
        
            II a, b, c, d, x(k + 0), S41, &HF4292244
            II d, a, b, c, x(k + 7), S42, &H432AFF97
            II c, d, a, b, x(k + 14), S43, &HAB9423A7
            II b, c, d, a, x(k + 5), S44, &HFC93A039
            II a, b, c, d, x(k + 12), S41, &H655B59C3
            II d, a, b, c, x(k + 3), S42, &H8F0CCC92
            II c, d, a, b, x(k + 10), S43, &HFFEFF47D
            II b, c, d, a, x(k + 1), S44, &H85845DD1
            II a, b, c, d, x(k + 8), S41, &H6FA87E4F
            II d, a, b, c, x(k + 15), S42, &HFE2CE6E0
            II c, d, a, b, x(k + 6), S43, &HA3014314
            II b, c, d, a, x(k + 13), S44, &H4E0811A1
            II a, b, c, d, x(k + 4), S41, &HF7537E82
            II d, a, b, c, x(k + 11), S42, &HBD3AF235
            II c, d, a, b, x(k + 2), S43, &H2AD7D2BB
            II b, c, d, a, x(k + 9), S44, &HEB86D391
        
            a = AddUnsigned(a, AA)
            b = AddUnsigned(b, BB)
            c = AddUnsigned(c, CC)
            d = AddUnsigned(d, DD)
        Next
        
        ' Step 5.  Output the 128 bit digest
                '=LCase(WordToHex(a) & WordToHex(b) & WordToHex(c) & WordToHex(d))
        MD5 = LCase(WordToHex(b) & WordToHex(c))
    End Function
      

  6.   

    完毕!真TMD长!上面这个模块你也可以到我的FTP上下载~ftp://my99.xicp.net/md5.bas
      

  7.   


    但是好像有错误
    RShiftSigned = Int(lValue / m_l2Power(iShiftBits))
    报错说除数为零
      

  8.   

    555555555md5是不可逆加密算法,~~不能解密,它的原理就像x+y=100一样,有N多种可能,也就是一个加密后的字符串对应N个可能是正确的正确密码~知道了吧~~
    这个模块是拿别人的,不过我有个16位的,那个可能还简单些~
      

  9.   

    Private Const BITS_TO_A_BYTE = 8
    Private Const BYTES_TO_A_WORD = 4
    Private Const BITS_TO_A_WORD = 32Private 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 FunctionPrivate 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 FunctionPrivate Function RotateLeft(lValue, iShiftBits)
        RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits))
    End FunctionPrivate 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 FunctionPrivate Function md5_F(x, y, z)
        md5_F = (x And y) Or ((Not x) And z)
    End FunctionPrivate Function md5_G(x, y, z)
        md5_G = (x And z) Or (y And (Not z))
    End FunctionPrivate Function md5_H(x, y, z)
        md5_H = (x Xor y Xor z)
    End FunctionPrivate Function md5_I(x, y, z)
        md5_I = (y Xor (x Or (Not z)))
    End FunctionPrivate 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 SubPrivate 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 SubPrivate 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 SubPrivate 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 SubPrivate 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, lBytePosition)    lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3)
        lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29)
        
        ConvertToWordArray = lWordArray
    End FunctionPrivate Function WordToHex(lValue)
        Dim lByte
        Dim lCount
        
        For lCount = 0 To 3
            lByte = RShift(lValue, lCount * BITS_TO_A_BYTE) And m_lOnBits(BITS_TO_A_BYTE - 1)
            WordToHex = WordToHex & Right("0" & Hex(lByte), 2)
        Next
    End Function
      

  10.   

    Public Function MD5(sMessage)    '用的时侯就调用这个函数!!!!!
        m_lOnBits(0) = CLng(1)
        m_lOnBits(1) = CLng(3)
        m_lOnBits(2) = CLng(7)
        m_lOnBits(3) = CLng(15)
        m_lOnBits(4) = CLng(31)
        m_lOnBits(5) = CLng(63)
        m_lOnBits(6) = CLng(127)
        m_lOnBits(7) = CLng(255)
        m_lOnBits(8) = CLng(511)
        m_lOnBits(9) = CLng(1023)
        m_lOnBits(10) = CLng(2047)
        m_lOnBits(11) = CLng(4095)
        m_lOnBits(12) = CLng(8191)
        m_lOnBits(13) = CLng(16383)
        m_lOnBits(14) = CLng(32767)
        m_lOnBits(15) = CLng(65535)
        m_lOnBits(16) = CLng(131071)
        m_lOnBits(17) = CLng(262143)
        m_lOnBits(18) = CLng(524287)
        m_lOnBits(19) = CLng(1048575)
        m_lOnBits(20) = CLng(2097151)
        m_lOnBits(21) = CLng(4194303)
        m_lOnBits(22) = CLng(8388607)
        m_lOnBits(23) = CLng(16777215)
        m_lOnBits(24) = CLng(33554431)
        m_lOnBits(25) = CLng(67108863)
        m_lOnBits(26) = CLng(134217727)
        m_lOnBits(27) = CLng(268435455)
        m_lOnBits(28) = CLng(536870911)
        m_lOnBits(29) = CLng(1073741823)
        m_lOnBits(30) = CLng(2147483647)
        
        m_l2Power(0) = CLng(1)
        m_l2Power(1) = CLng(2)
        m_l2Power(2) = CLng(4)
        m_l2Power(3) = CLng(8)
        m_l2Power(4) = CLng(16)
        m_l2Power(5) = CLng(32)
        m_l2Power(6) = CLng(64)
        m_l2Power(7) = CLng(128)
        m_l2Power(8) = CLng(256)
        m_l2Power(9) = CLng(512)
        m_l2Power(10) = CLng(1024)
        m_l2Power(11) = CLng(2048)
        m_l2Power(12) = CLng(4096)
        m_l2Power(13) = CLng(8192)
        m_l2Power(14) = CLng(16384)
        m_l2Power(15) = CLng(32768)
        m_l2Power(16) = CLng(65536)
        m_l2Power(17) = CLng(131072)
        m_l2Power(18) = CLng(262144)
        m_l2Power(19) = CLng(524288)
        m_l2Power(20) = CLng(1048576)
        m_l2Power(21) = CLng(2097152)
        m_l2Power(22) = CLng(4194304)
        m_l2Power(23) = CLng(8388608)
        m_l2Power(24) = CLng(16777216)
        m_l2Power(25) = CLng(33554432)
        m_l2Power(26) = CLng(67108864)
        m_l2Power(27) = CLng(134217728)
        m_l2Power(28) = CLng(268435456)
        m_l2Power(29) = CLng(536870912)
        m_l2Power(30) = CLng(1073741824)
        Dim x
        Dim k
        Dim AA
        Dim BB
        Dim CC
        Dim DD
        Dim a
        Dim b
        Dim c
        Dim d
        
        Const S11 = 7
        Const S12 = 12
        Const S13 = 17
        Const S14 = 22
        Const S21 = 5
        Const S22 = 9
        Const S23 = 14
        Const S24 = 20
        Const S31 = 4
        Const S32 = 11
        Const S33 = 16
        Const S34 = 23
        Const S41 = 6
        Const S42 = 10
        Const S43 = 15
        Const S44 = 21    x = ConvertToWordArray(sMessage)
        
        a = &H67452301
        b = &HEFCDAB89
        c = &H98BADCFE
        d = &H10325476    For k = 0 To UBound(x) Step 16
            AA = a
            BB = b
            CC = c
            DD = d
        
            md5_FF a, b, c, d, x(k + 15), S11, &HD76AA478
            md5_FF d, a, b, c, x(k + 14), S12, &HE8C7B756
            md5_FF c, d, a, b, x(k + 13), S13, &H242070DB
            md5_FF b, c, d, a, x(k + 12), S14, &HC1BDCEEE
            md5_FF a, b, c, d, x(k + 11), S11, &HF57C0FAF
            md5_FF d, a, b, c, x(k + 10), S12, &H4787C62A
            md5_FF c, d, a, b, x(k + 9), S13, &HA8304613
            md5_FF b, c, d, a, x(k + 8), S14, &HFD469501
            md5_FF a, b, c, d, x(k + 7), S11, &H698098D8
            md5_FF d, a, b, c, x(k + 6), S12, &H8B44F7AF
            md5_FF c, d, a, b, x(k + 5), S13, &HFFFF5BB1
            md5_FF b, c, d, a, x(k + 4), S14, &H895CD7BE
            md5_FF a, b, c, d, x(k + 3), S11, &H6B901122
            md5_FF d, a, b, c, x(k + 2), S12, &HFD987193
            md5_FF c, d, a, b, x(k + 1), S13, &HA679438E
            md5_FF b, c, d, a, x(k + 0), S14, &H49B40821
        
            md5_GG a, b, c, d, x(k + 1), S21, &HF61E2562
            md5_GG d, a, b, c, x(k + 6), S22, &HC040B340
            md5_GG c, d, a, b, x(k + 11), S23, &H265E5A51
            md5_GG b, c, d, a, x(k + 0), S24, &HE9B6C7AA
            md5_GG a, b, c, d, x(k + 5), S21, &HD62F105D
            md5_GG d, a, b, c, x(k + 10), S22, &H2441453
            md5_GG c, d, a, b, x(k + 15), S23, &HD8A1E681
            md5_GG b, c, d, a, x(k + 4), S24, &HE7D3FBC8
            md5_GG a, b, c, d, x(k + 9), S21, &H21E1CDE6
            md5_GG d, a, b, c, x(k + 14), S22, &HC33707D6
            md5_GG c, d, a, b, x(k + 3), S23, &HF4D50D87
            md5_GG b, c, d, a, x(k + 8), S24, &H455A14ED
            md5_GG a, b, c, d, x(k + 13), S21, &HA9E3E905
            md5_GG d, a, b, c, x(k + 2), S22, &HFCEFA3F8
            md5_GG c, d, a, b, x(k + 7), S23, &H676F02D9
            md5_GG b, c, d, a, x(k + 12), S24, &H8D2A4C8A
                
            md5_HH a, b, c, d, x(k + 5), S31, &HFFFA3942
            md5_HH d, a, b, c, x(k + 8), S32, &H8771F681
            md5_HH c, d, a, b, x(k + 11), S33, &H6D9D6122
            md5_HH b, c, d, a, x(k + 14), S34, &HFDE5380C
            md5_HH a, b, c, d, x(k + 1), S31, &HA4BEEA44
            md5_HH d, a, b, c, x(k + 4), S32, &H4BDECFA9
            md5_HH c, d, a, b, x(k + 7), S33, &HF6BB4B60
            md5_HH b, c, d, a, x(k + 10), S34, &HBEBFBC70
            md5_HH a, b, c, d, x(k + 13), S31, &H289B7EC6
            md5_HH d, a, b, c, x(k + 0), S32, &HEAA127FA
            md5_HH c, d, a, b, x(k + 3), S33, &HD4EF3085
            md5_HH b, c, d, a, x(k + 6), S34, &H4881D05
            md5_HH a, b, c, d, x(k + 9), S31, &HD9D4D039
            md5_HH d, a, b, c, x(k + 12), S32, &HE6DB99E5
            md5_HH c, d, a, b, x(k + 15), S33, &H1FA27CF8
            md5_HH b, c, d, a, x(k + 2), S34, &HC4AC5665
        
            md5_II a, b, c, d, x(k + 0), S41, &HF4292244
            md5_II d, a, b, c, x(k + 7), S42, &H432AFF97
            md5_II c, d, a, b, x(k + 14), S43, &HAB9423A7
            md5_II b, c, d, a, x(k + 5), S44, &HFC93A039
            md5_II a, b, c, d, x(k + 12), S41, &H655B59C3
            md5_II d, a, b, c, x(k + 3), S42, &H8F0CCC92
            md5_II c, d, a, b, x(k + 10), S43, &HFFEFF47D
            md5_II b, c, d, a, x(k + 1), S44, &H85845DD1
            md5_II a, b, c, d, x(k + 8), S41, &H6FA87E4F
            md5_II d, a, b, c, x(k + 15), S42, &HFE2CE6E0
            md5_II c, d, a, b, x(k + 6), S43, &HA3014314
            md5_II b, c, d, a, x(k + 13), S44, &H4E0811A1
            md5_II a, b, c, d, x(k + 4), S41, &HF7537E82
            md5_II d, a, b, c, x(k + 11), S42, &HBD3AF235
            md5_II c, d, a, b, x(k + 2), S43, &H2AD7D2BB
            md5_II b, c, d, a, x(k + 9), S44, &HEB86D391
        
            a = AddUnsigned(a, AA)
            b = AddUnsigned(b, BB)
            c = AddUnsigned(c, CC)
            d = AddUnsigned(d, DD)
        Next
        
        'MD5 = LCase(WordToHex(a) & WordToHex(b) & WordToHex(c) & WordToHex(d))
        MD5=LCase(WordToHex(b) & WordToHex(c))  
    End Function
      

  11.   

    呵呵,您误会了。我不是这个意思
    我指的是这样
    加密 Txt1=md5(password)
    解密 Txt2=unMd5(Txt1, password)
    也就是说,我好像没有发现解密的函数
    ============================
    Sorry,小生愚昧,望指点
      

  12.   

    VB中实现MD5加密  
    使用方法:msgbox DigestStrToHexStr("111")源代码:-----------剪切线------------------------------------------------------------Option Explicit'/******************************************************************************
    ' *  Copyright (C) 2000 by Robert Hubley.                                      *
    ' *  All rights reserved.                                                      *
    ' *                                                                            *
    ' *  This software is provided ``AS IS'' and any express or implied            *
    ' *  warranties, including, but not limited to, the implied warranties of      *
    ' *  merchantability and fitness for a particular purpose, are disclaimed.     *
    ' *  In no event shall the authors be liable for any direct, indirect,         *
    ' *  incidental, special, exemplary, or consequential damages (including, but  *
    ' *  not limited to, procurement of substitute goods or services; loss of use, *
    ' *  data, or profits; or business interruption) however caused and on any     *
    ' *  theory of liability, whether in contract, strict liability, or tort       *
    ' *  (including negligence or otherwise) arising in any way out of the use of  *
    ' *  this software, even if advised of the possibility of such damage.         *
    ' *                                                                            *
    ' ******************************************************************************
    '
    '  CLASS: MD5
    '
    '  DESCRIPTION:
    '     This is a class which encapsulates a set of MD5 Message Digest functions.
    '     MD5 algorithm produces a 128 bit digital fingerprint (signature) from an
    '     dataset of arbitrary length.  For details see RFC 1321 (summarized below).
    '     This implementation is derived from the RSA Data Security, Inc. MD5 Message-Digest
    '     algorithm reference implementation (originally written in C)
    '
    '  AUTHOR:
    '     Robert M. Hubley 12/1999
    '
    '
    '  NOTES:
    '      Network Working Group                                    R. Rivest
    '      Request for Comments: 1321     MIT Laboratory for Computer Science
    '                                             and RSA Data Security, Inc.
    '                                                              April 1992
    '
    '
    '                           The MD5 Message-Digest Algorithm
    '
    '      Summary
    '
    '         This document describes the MD5 message-digest algorithm. The
    '         algorithm takes as input a message of arbitrary length and produces
    '         as output a 128-bit "fingerprint" or "message digest" of the input.
    '         It is conjectured that it is computationally infeasible to produce
    '         two messages having the same message digest, or to produce any
    '         message having a given prespecified target message digest. The MD5
    '         algorithm is intended for digital signature applications, where a
    '         large file must be "compressed" in a secure manner before being
    '         encrypted with a private (secret) key under a public-key cryptosystem
    '         such as RSA.
    '
    '         The MD5 algorithm is designed to be quite fast on 32-bit machines. In
    '         addition, the MD5 algorithm does not require any large substitution
    '         tables; the algorithm can be coded quite compactly.
    '
    '         The MD5 algorithm is an extension of the MD4 message-digest algorithm
    '         1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
    '         design. MD5 was designed because it was felt that MD4 was perhaps
    '         being adopted for use more quickly than justified by the existing
    '         critical review; because MD4 was designed to be exceptionally fast,
    '         it is "at the edge" in terms of risking successful cryptanalytic
    '         attack. MD5 backs off a bit, giving up a little in speed for a much
    '         greater likelihood of ultimate security. It incorporates some
    '         suggestions made by various reviewers, and contains additional
    '         optimizations. The MD5 algorithm is being placed in the public domain
    '         for review and possible adoption as a standard.
    '
    '         RFC Author:
    '         Ronald L.Rivest
    '         Massachusetts Institute of Technology
    '         Laboratory for Computer Science
    '         NE43 -324545    Technology Square
    '         Cambridge, MA  02139-1986
    '         Phone: (617) 253-5880
    '         EMail:    Rivest@ theory.lcs.mit.edu
    '
    '
    '
    '  CHANGE HISTORY:
    '
    '     0.1.0  RMH    1999/12/29      Original version
    '
    '
      

  13.   

    '=
    '= Class Constants
    '=
    Private Const OFFSET_4 = 4294967296#
    Private Const MAXINT_4 = 2147483647Private Const S11 = 7
    Private Const S12 = 12
    Private Const S13 = 17
    Private Const S14 = 22
    Private Const S21 = 5
    Private Const S22 = 9
    Private Const S23 = 14
    Private Const S24 = 20
    Private Const S31 = 4
    Private Const S32 = 11
    Private Const S33 = 16
    Private Const S34 = 23
    Private Const S41 = 6
    Private Const S42 = 10
    Private Const S43 = 15
    Private Const S44 = 21
    '=
    '= Class Variables
    '=
    Private State(4) As Long
    Private ByteCounter As Long
    Private ByteBuffer(63) As Byte
    '=
    '= Class Properties
    '=
    Property Get RegisterA() As String
        RegisterA = State(1)
    End PropertyProperty Get RegisterB() As String
        RegisterB = State(2)
    End PropertyProperty Get RegisterC() As String
        RegisterC = State(3)
    End PropertyProperty Get RegisterD() As String
        RegisterD = State(4)
    End Property
    '=
    '= Class Functions
    '='
    ' Function to quickly digest a file into a hex string
    '
    Public Function DigestFileToHexStr(FileName As String) As String
        Open FileName For Binary Access Read As #1
        MD5Init
        Do While Not EOF(1)
            Get #1, , ByteBuffer
            If Loc(1) < LOF(1) Then
                ByteCounter = ByteCounter + 64
                MD5Transform ByteBuffer
            End If
        Loop
        ByteCounter = ByteCounter + (LOF(1) Mod 64)
        Close #1
        MD5Final
        DigestFileToHexStr = GetValues
    End Function'
    ' Function to digest a text string and output the result as a string
    ' of hexadecimal characters.
    '
    Public Function DigestStrToHexStr(SourceString As String) As String
        MD5Init
        MD5Update Len(SourceString), StringToArray(SourceString)
        MD5Final
        DigestStrToHexStr = GetValues
    End Function'
    ' A utility function which converts a string into an array of
    ' bytes.
    '
    Private Function StringToArray(InString As String) As Byte()
        Dim I As Integer
        Dim bytBuffer() As Byte
        ReDim bytBuffer(Len(InString))
        For I = 0 To Len(InString) - 1
            bytBuffer(I) = Asc(Mid(InString, I + 1, 1))
        Next I
        StringToArray = bytBuffer
    End Function'
    ' Concatenate the four state vaules into one string
    '
    Public Function GetValues() As String
        GetValues = LongToString(State(1)) & LongToString(State(2)) & LongToString(State(3)) & LongToString(State(4))
    End Function'
    ' Convert a Long to a Hex string
    '
    Private Function LongToString(Num As Long) As String
            Dim a As Byte
            Dim b As Byte
            Dim c As Byte
            Dim d As Byte
            
            a = Num And &HFF&
            If a < 16 Then
                LongToString = "0" & Hex(a)
            Else
                LongToString = Hex(a)
            End If
                   
            b = (Num And &HFF00&) \ 256
            If b < 16 Then
                LongToString = LongToString & "0" & Hex(b)
            Else
                LongToString = LongToString & Hex(b)
            End If
            
            c = (Num And &HFF0000) \ 65536
            If c < 16 Then
                LongToString = LongToString & "0" & Hex(c)
            Else
                LongToString = LongToString & Hex(c)
            End If
           
            If Num < 0 Then
                d = ((Num And &H7F000000) \ 16777216) Or &H80&
            Else
                d = (Num And &HFF000000) \ 16777216
            End If
            
            If d < 16 Then
                LongToString = LongToString & "0" & Hex(d)
            Else
                LongToString = LongToString & Hex(d)
            End If
        
    End Function'
      

  14.   

    '
    ' Initialize the class
    '   This must be called before a digest calculation is started
    '
    Public Sub MD5Init()
        ByteCounter = 0
        State(1) = UnsignedToLong(1732584193#)
        State(2) = UnsignedToLong(4023233417#)
        State(3) = UnsignedToLong(2562383102#)
        State(4) = UnsignedToLong(271733878#)
    End Sub'
    ' MD5 Final
    '
    Public Sub MD5Final()
        Dim dblBits As Double
        
        Dim padding(72) As Byte
        Dim lngBytesBuffered As Long
        
        padding(0) = &H80
        
        dblBits = ByteCounter * 8
        
        ' Pad out
        lngBytesBuffered = ByteCounter Mod 64
        If lngBytesBuffered <= 56 Then
            MD5Update 56 - lngBytesBuffered, padding
        Else
            MD5Update 120 - ByteCounter, padding
        End If
        
        
        padding(0) = UnsignedToLong(dblBits) And &HFF&
        padding(1) = UnsignedToLong(dblBits) \ 256 And &HFF&
        padding(2) = UnsignedToLong(dblBits) \ 65536 And &HFF&
        padding(3) = UnsignedToLong(dblBits) \ 16777216 And &HFF&
        padding(4) = 0
        padding(5) = 0
        padding(6) = 0
        padding(7) = 0
        
        MD5Update 8, padding
    End Sub'
    ' Break up input stream into 64 byte chunks
    '
    Public Sub MD5Update(InputLen As Long, InputBuffer() As Byte)
        Dim II As Integer
        Dim I As Integer
        Dim J As Integer
        Dim K As Integer
        Dim lngBufferedBytes As Long
        Dim lngBufferRemaining As Long
        Dim lngRem As Long
        
        lngBufferedBytes = ByteCounter Mod 64
        lngBufferRemaining = 64 - lngBufferedBytes
        ByteCounter = ByteCounter + InputLen
        ' Use up old buffer results first
        If InputLen >= lngBufferRemaining Then
            For II = 0 To lngBufferRemaining - 1
                ByteBuffer(lngBufferedBytes + II) = InputBuffer(II)
            Next II
            MD5Transform ByteBuffer
            
            lngRem = (InputLen) Mod 64
            ' The transfer is a multiple of 64 lets do some transformations
            For I = lngBufferRemaining To InputLen - II - lngRem Step 64
                For J = 0 To 63
                    ByteBuffer(J) = InputBuffer(I + J)
                Next J
                MD5Transform ByteBuffer
            Next I
            lngBufferedBytes = 0
        Else
          I = 0
        End If
        
        ' Buffer any remaining input
        For K = 0 To InputLen - I - 1
            ByteBuffer(lngBufferedBytes + K) = InputBuffer(I + K)
        Next K
        
    End Sub'
    ' MD5 Transform
    '
    Private Sub MD5Transform(Buffer() As Byte)
        Dim x(16) As Long
        Dim a As Long
        Dim b As Long
        Dim c As Long
        Dim d As Long
        
        a = State(1)
        b = State(2)
        c = State(3)
        d = State(4)
        
        Decode 64, x, Buffer    ' Round 1
        FF a, b, c, d, x(0), S11, -680876936
        FF d, a, b, c, x(1), S12, -389564586
        FF c, d, a, b, x(2), S13, 606105819
        FF b, c, d, a, x(3), S14, -1044525330
        FF a, b, c, d, x(4), S11, -176418897
        FF d, a, b, c, x(5), S12, 1200080426
        FF c, d, a, b, x(6), S13, -1473231341
        FF b, c, d, a, x(7), S14, -45705983
        FF a, b, c, d, x(8), S11, 1770035416
        FF d, a, b, c, x(9), S12, -1958414417
        FF c, d, a, b, x(10), S13, -42063
        FF b, c, d, a, x(11), S14, -1990404162
        FF a, b, c, d, x(12), S11, 1804603682
        FF d, a, b, c, x(13), S12, -40341101
        FF c, d, a, b, x(14), S13, -1502002290
        FF b, c, d, a, x(15), S14, 1236535329
        
        ' Round 2
        GG a, b, c, d, x(1), S21, -165796510
        GG d, a, b, c, x(6), S22, -1069501632
        GG c, d, a, b, x(11), S23, 643717713
        GG b, c, d, a, x(0), S24, -373897302
        GG a, b, c, d, x(5), S21, -701558691
        GG d, a, b, c, x(10), S22, 38016083
        GG c, d, a, b, x(15), S23, -660478335
        GG b, c, d, a, x(4), S24, -405537848
        GG a, b, c, d, x(9), S21, 568446438
        GG d, a, b, c, x(14), S22, -1019803690
        GG c, d, a, b, x(3), S23, -187363961
        GG b, c, d, a, x(8), S24, 1163531501
        GG a, b, c, d, x(13), S21, -1444681467
        GG d, a, b, c, x(2), S22, -51403784
        GG c, d, a, b, x(7), S23, 1735328473
        GG b, c, d, a, x(12), S24, -1926607734
        
        ' Round 3
        HH a, b, c, d, x(5), S31, -378558
        HH d, a, b, c, x(8), S32, -2022574463
        HH c, d, a, b, x(11), S33, 1839030562
        HH b, c, d, a, x(14), S34, -35309556
        HH a, b, c, d, x(1), S31, -1530992060
        HH d, a, b, c, x(4), S32, 1272893353
        HH c, d, a, b, x(7), S33, -155497632
        HH b, c, d, a, x(10), S34, -1094730640
        HH a, b, c, d, x(13), S31, 681279174
        HH d, a, b, c, x(0), S32, -358537222
        HH c, d, a, b, x(3), S33, -722521979
        HH b, c, d, a, x(6), S34, 76029189
        HH a, b, c, d, x(9), S31, -640364487
        HH d, a, b, c, x(12), S32, -421815835
        HH c, d, a, b, x(15), S33, 530742520
        HH b, c, d, a, x(2), S34, -995338651
        
      

  15.   

    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=0X76543210 4、
    处理位操作函数: 
    X,Y,Z为32位整数。 
    F(X,Y,Z) = X&Y|NOT(X)&Z
    G(X,Y,Z) = X&Z|Y?(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 + DD end /* 结束对I的循环*/6、
    输出结果。