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
'******************************************************************************* ' 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 '*******************************************************************************
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. '*******************************************************************************
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. '*******************************************************************************
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
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
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
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 ' '
'= '= 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'
' ' 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
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、 输出结果。
'*******************************************************************************
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
'*******************************************************************************
' 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
'*******************************************************************************
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.
'*******************************************************************************
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.
'*******************************************************************************
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
但是好像有错误
RShiftSigned = Int(lValue / m_l2Power(iShiftBits))
报错说除数为零
这个模块是拿别人的,不过我有个16位的,那个可能还简单些~
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
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
我指的是这样
加密 Txt1=md5(password)
解密 Txt2=unMd5(Txt1, password)
也就是说,我好像没有发现解密的函数
============================
Sorry,小生愚昧,望指点
使用方法: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
'
'
'= 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'
' 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
补位:
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、
输出结果。