Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' http://forum.qbasicnews.com/index.php?topic=13371.0
- ' MD5 Cryptographic Hash Function
- ' stylin
- ' on: November 01, 2009, 05:49:02 PM
- ' Here's some code I write for QBasic or QuickBASIC that calculates MD5 hashes of strings, files or arbitrary in-memory data. It's painfully slow since I had to simulate modulo 32-bit addition with unsigned integers -- see MD5AddModulo32&. It could be ' sped up significantly by implementing MD5HashBlock and its helper routines, the "meat" of the algorithm, in assembly, but I figured it would be fun to try a pure QB solution.
- ' This code is adapted from the reference implementation of The MD5 Message-Digest Algorithm (RFC 1321). It should be pretty easy to follow; I've tried to comment the parts that need explanation, but for more detailed information on the MD5 algorithm ' itself, see the RFC and the Wikipedia page. Hope someone finds this useful.
- '' PUBLIC API
- '' function: MD5HashString$
- '' Returns the 32-character hexadecimal string representation of the
- '' message digest of `message`.
- DECLARE FUNCTION MD5HashString$ ( message AS STRING )
- '' function: MD5HashFile$
- '' Returns the 32-character hexadecimal string representation of the
- '' message digest of the file `fileName`.
- DECLARE FUNCTION MD5HashFile$ ( fileName AS STRING )
- '' type: MD5HashState
- '' Stores the state of a hash operation. Use MD5Initialize, followed by calls
- '' to MD5Update/MD5UpdateAux for all message bytes, then
- '' MD5Finalize/MD5FinalizeAux to retrieve the message digest. (See
- '' implementation for MD5HashFile$.) All fields are considered private.
- TYPE MD5HashState
- bitCount AS LONG
- bitCount2 AS LONG
- a AS LONG
- b AS LONG
- c AS LONG
- d AS LONG
- block AS STRING * 64
- END TYPE
- '' sub: MD5Initialize
- '' Prepares `state` for calls to Update.
- DECLARE SUB MD5Initialize ( state AS MD5HashState )
- '' sub: MD5Update
- '' Begins or continues a hashing operation on `state` with the bytes in
- '' `source`.
- DECLARE SUB MD5Update ( state AS MD5HashState, source AS STRING )
- '' sub: MD5UpdateAux
- '' Begins or continues a hashing operation on `state` with `sourceLength`
- '' bytes starting at address `sourcePtr`.
- DECLARE SUB MD5UpdateAux ( state AS MD5HashState, sourcePtr AS INTEGER, sourceLength AS INTEGER )
- '' sub: MD5Finalize
- '' Finishes the hashing operation on `state`, allocating and placing the
- '' 16-byte message digest in `digest`.
- DECLARE SUB MD5Finalize ( state AS MD5HashState, digest AS STRING )
- '' sub: MD5FinalizeAux
- '' Finishes the hashing operation on `state`, placing the 16-byte message
- '' digest in the pre-allocated memory starting at `digestPtr`.
- DECLARE SUB MD5FinalizeAux ( state AS MD5HashState, digestPtr AS INTEGER )
- '' function: MD5GetHexFromBytes$
- '' Returns the (2 * `srcLen`)-character hexadecimal string representation of
- '' the bytes starting at `srcPtr`.
- DECLARE FUNCTION MD5GetHexFromBytes$ ( srcPtr AS INTEGER, srcLen AS INTEGER )
- '' function: MD5GetStringDataPtr%
- '' Helper to retrieve the near address of first character of variable-length
- '' strings and string parameters.
- DECLARE FUNCTION MD5GetStringDataPtr% ( s AS STRING )
- '' INTERNAL API
- DECLARE SUB MD5HashBlock ( state AS MD5HashState, blockPtr AS INTEGER )
- DECLARE FUNCTION MD5RoundF& ( x AS LONG, y AS LONG, z AS LONG )
- DECLARE FUNCTION MD5RoundG& ( x AS LONG, y AS LONG, z AS LONG )
- DECLARE FUNCTION MD5RoundH& ( x AS LONG, y AS LONG, z AS LONG )
- DECLARE FUNCTION MD5RoundI& ( x AS LONG, y AS LONG, z AS LONG )
- DECLARE SUB MD5FF ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DECLARE SUB MD5GG ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DECLARE SUB MD5HH ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DECLARE SUB MD5II ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DECLARE FUNCTION MD5AddModulo32& ( a AS LONG, b AS LONG )
- DECLARE FUNCTION MD5RotateLeft& ( n AS LONG, s AS INTEGER )
- DECLARE SUB MD5MemCopy ( dstPtr AS INTEGER, srcPtr AS INTEGER, length AS INTEGER )
- '' ::::: [demo code]
- ' d41d8cd98f00b204e9800998ecf8427e
- PRINT MD5HashString$( "" )
- ' 0cc175b9c0f1b6a831c399e269772661
- PRINT MD5HashString$( "a" )
- ' 900150983cd24fb0d6963f7d28e17f72
- PRINT MD5HashString$( "abc" )
- ' f96b697d7cb7938d525a2f31aaf161d0
- PRINT MD5HashString$( "message digest" )
- ' c3fcd3d76192e4007dfb496cca67e13b
- PRINT MD5HashString$( "abcdefghijklmnopqrstuvwxyz" )
- ' d174ab98d277d9f5a5611c2c9f419d9f
- PRINT MD5HashString$( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" )
- ' 57edf4a22be3c955ac49da2e2107b67a
- PRINT MD5HashString$( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" )
- END
- '' ::::: [/demo code]
- DEFLNG a-z
- FUNCTION MD5HashString$ ( message AS STRING )
- DIM state AS MD5HashState
- DIM digest AS STRING
- MD5Initialize state
- MD5Update state, message
- MD5Finalize state, digest
- MD5HashString$ = MD5GetHexFromBytes$( MD5GetStringDataPtr%( digest ), LEN( digest ) )
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5HashFile$ ( fileName AS STRING )
- DIM fileNum AS INTEGER : fileNum = FREEFILE
- OPEN fileName FOR BINARY ACCESS READ AS #fileNum
- DIM state AS MD5HashState
- MD5Initialize state
- DIM bytesLeft AS LONG : bytesLeft = LOF( fileNum )
- DIM buffer AS STRING : buffer = SPACE$( 2048 )
- DO WHILE bytesLeft
- IF ( bytesLeft < LEN( buffer ) ) THEN
- buffer = SPACE$( bytesLeft )
- END IF
- GET #filenum, , buffer
- bytesLeft = bytesLeft - LEN( buffer )
- MD5Update state, buffer
- LOOP
- CLOSE #filenum
- DIM digest AS STRING
- MD5Finalize state, digest
- MD5HashFile$ = MD5GetHexFromBytes$( MD5GetStringDataPtr%( digest ), LEN( digest ) )
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5GetHexFromBytes$ ( srcPtr AS INTEGER, srcLen AS INTEGER )
- DIM result AS STRING * 32
- FOR i = 0 TO srcLen - 1
- DIM b AS INTEGER : b = PEEK( srcPtr + i )
- DIM highNibble AS INTEGER : highNibble = ( b AND &HF0 ) \ 16
- DIM lowNibble AS INTEGER : lowNibble = ( b AND &H0F )
- MID$( result, (i*2) + 1, 1 ) = HEX$( highNibble )
- MID$( result, (i*2) + 2, 1 ) = HEX$( lowNibble )
- NEXT i
- MD5GetHexFromBytes$ = result
- END FUNCTION
- DEFLNG a-z
- SUB MD5Encode ( dstPtr AS INTEGER, srcPtr AS INTEGER, n AS INTEGER )
- DIM i AS INTEGER
- DIM j AS INTEGER
- DO WHILE j < n
- POKE dstPtr + j , PEEK( srcPtr + i + 0 )
- POKE dstPtr + j + 1, PEEK( srcPtr + i + 1 )
- POKE dstPtr + j + 2, PEEK( srcPtr + i + 2 )
- POKE dstPtr + j + 3, PEEK( srcPtr + i + 3 )
- i = i + 4
- j = j + 4
- LOOP
- END SUB
- DEFLNG a-z
- SUB MD5Decode ( dstPtr AS INTEGER, srcPtr AS INTEGER, n AS INTEGER )
- DIM i AS INTEGER
- DIM j AS INTEGER
- DO WHILE j < n
- POKE dstPtr + j , PEEK( srcPtr + i + 0 )
- POKE dstPtr + j + 1, PEEK( srcPtr + i + 1 )
- POKE dstPtr + j + 2, PEEK( srcPtr + i + 2 )
- POKE dstPtr + j + 3, PEEK( srcPtr + i + 3 )
- i = i + 4
- j = j + 4
- LOOP
- END SUB
- DEFLNG a-z
- SUB MD5Initialize ( state AS MD5HashState )
- ' prime state variables with these magic numbers:
- state.a = &h67452301
- state.b = &hefcdab89
- state.c = &h98badcfe
- state.d = &h10325476
- END SUB
- DEFLNG a-z
- SUB MD5Update ( state AS MD5HashState, bytes AS STRING )
- MD5UpdateAux state, MD5GetStringDataPtr%( bytes ), LEN( bytes )
- END SUB
- DEFLNG a-z
- SUB MD5UpdateAux ( state AS MD5HashState, srcPtr AS INTEGER, srcLen AS INTEGER )
- DIM index AS INTEGER
- DIM partLen AS INTEGER
- DIM i AS INTEGER
- index = ( state.bitCount \ 8 ) AND &H3f
- ' update bit count..
- state.bitCount = MD5AddModulo32&( state.bitCount, srcLen * 8 )
- IF ( state.bitCount < srcLen * 8 ) THEN
- state.bitCount2 = state.bitCount2 + 1
- state.bitCount2 = MD5AddModulo32&( state.bitCount2, ( srcLen / 2& ^ 29& ) )
- END IF
- partLen = 64 - index
- i = 0
- IF ( srclen >= partlen ) THEN
- ' fill and hash buffer.
- MD5MemCopy VARPTR( state.block ) + index, srcPtr, partLen
- MD5HashBlock state, VARPTR( state.block )
- ' hash as many full-sized source blocks as possible.
- i = partlen
- DO WHILE i + 63 < srcLen
- MD5HashBlock state, srcPtr + i
- i = i + 64
- LOOP
- index = 0
- END IF
- ' buffer remaining source.
- MD5MemCopy VARPTR( state.block ) + index, srcPtr + i, srcLen - i
- END SUB
- DEFLNG a-z
- SUB MD5Finalize ( state AS MD5HashState, digest AS STRING )
- digest = SPACE$( 16 )
- MD5FinalizeAux state, MD5GetStringDataPtr%( digest )
- END SUB
- DEFLNG a-z
- SUB MD5FinalizeAux ( state AS MD5HashState, digestPtr AS INTEGER )
- ' storage for arbitrary padding lengths:
- DIM PADDING AS STRING * 64
- MID$( PADDING, 1, 1 ) = CHR$( &H80 )
- DIM index AS INTEGER
- DIM padLen AS INTEGER
- ' save bit count (up to padding bits)
- DIM bitCountStorage AS STRING * 8
- MD5Encode VARPTR( bitCountStorage ), VARPTR( state.bitCount ), 8
- ' 'append' and hash padding bytes (leaving 8 bytes for length).
- index = ( state.bitCount \ 8 ) AND &H3f
- IF ( index < 56 ) THEN
- padLen = 56 - index
- ELSE
- padLen = 120 - index
- END IF
- MD5UpdateAux state, VARPTR( PADDING ), padLen
- ' 'append' and hash the message length.
- MD5Update state, bitCountStorage
- ' state (abcd) now holds the final digest; MD5Encode to byte array.
- MD5Encode digestPtr, VARPTR( state.a ), 16
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5GetStringDataPtr% ( s AS STRING )
- DIM dataPtr AS DOUBLE
- dataPtr = PEEK( VARPTR( s ) + 2 )
- dataPtr = dataPtr + PEEK( VARPTR( s ) + 3 ) * 256#
- ' unsigned to signed
- IF ( dataPtr > 32767# ) THEN dataPtr = -(65535# - dataPtr + 1)
- MD5GetStringDataPtr% = CINT( dataPtr )
- END FUNCTION
- DEFLNG a-z
- SUB MD5MemCopy ( dstPtr AS INTEGER, srcPtr AS INTEGER, length AS INTEGER )
- FOR i = 0 TO length - 1
- POKE dstPtr + i, PEEK( srcPtr + i )
- NEXT i
- END SUB
- DEFLNG a-z
- CONST T1 = &hd76aa478
- CONST T2 = &he8c7b756
- CONST T3 = &h242070db
- CONST T4 = &hc1bdceee
- CONST T5 = &hf57c0faf
- CONST T6 = &h4787c62a
- CONST T7 = &ha8304613
- CONST T8 = &hfd469501
- CONST T9 = &h698098d8
- CONST T10 = &h8b44f7af
- CONST T11 = &hffff5bb1
- CONST T12 = &h895cd7be
- CONST T13 = &h6b901122
- CONST T14 = &hfd987193
- CONST T15 = &ha679438e
- CONST T16 = &h49b40821
- CONST T17 = &hf61e2562
- CONST T18 = &hc040b340
- CONST T19 = &h265e5a51
- CONST T20 = &he9b6c7aa
- CONST T21 = &hd62f105d
- CONST T22 = &h02441453
- CONST T23 = &hd8a1e681
- CONST T24 = &he7d3fbc8
- CONST T25 = &h21e1cde6
- CONST T26 = &hc33707d6
- CONST T27 = &hf4d50d87
- CONST T28 = &h455a14ed
- CONST T29 = &ha9e3e905
- CONST T30 = &hfcefa3f8
- CONST T31 = &h676f02d9
- CONST T32 = &h8d2a4c8a
- CONST T33 = &hfffa3942
- CONST T34 = &h8771f681
- CONST T35 = &h6d9d6122
- CONST T36 = &hfde5380c
- CONST T37 = &ha4beea44
- CONST T38 = &h4bdecfa9
- CONST T39 = &hf6bb4b60
- CONST T40 = &hbebfbc70
- CONST T41 = &h289b7ec6
- CONST T42 = &heaa127fa
- CONST T43 = &hd4ef3085
- CONST T44 = &h04881d05
- CONST T45 = &hd9d4d039
- CONST T46 = &he6db99e5
- CONST T47 = &h1fa27cf8
- CONST T48 = &hc4ac5665
- CONST T49 = &hf4292244
- CONST T50 = &h432aff97
- CONST T51 = &hab9423a7
- CONST T52 = &hfc93a039
- CONST T53 = &h655b59c3
- CONST T54 = &h8f0ccc92
- CONST T55 = &hffeff47d
- CONST T56 = &h85845dd1
- CONST T57 = &h6fa87e4f
- CONST T58 = &hfe2ce6e0
- CONST T59 = &ha3014314
- CONST T60 = &h4e0811a1
- CONST T61 = &hf7537e82
- CONST T62 = &hbd3af235
- CONST T63 = &h2ad7d2bb
- CONST T64 = &heb86d391
- ' signed/unsigned conversions:
- '
- ' unsigned to signed:
- ' if( value > MAX_SIGNED_VALUE ) then
- ' value = -( MAX_UNSIGNED_VALUE - value + 1 )
- ' end if
- '
- ' signed to unsigned:
- ' if( value < 0 ) then
- ' value = MAX_UNSIGNED_VALUE + value + 1
- ' end if
- ' The following is used instead of "a + b" where necessary to provide addition
- ' modulo 32-bit of unsigned integers; needed because
- ' 1) QuickBASIC/QB throws an error on additive overflow, and
- ' 2) QuickBASIC/QB has no unsigned integer types.
- DEFLNG a-z
- FUNCTION MD5AddModulo32& ( a AS LONG, b AS LONG )
- DIM aa AS DOUBLE : aa = CDBL( a )
- DIM bb AS DOUBLE : bb = CDBL( b )
- ' signed to unsigned
- IF ( a < 0 ) THEN aa = 4294967295# + a + 1
- IF ( b < 0 ) THEN bb = 4294967295# + b + 1
- DIM cc AS DOUBLE : cc = aa + bb
- ' keep 32-bit portion ( cc = cc and &hFFFFFFFF )
- IF ( cc > 4294967295# ) THEN cc = cc - 4294967296#
- ' unsigned to signed
- IF ( cc > 2147483647# ) THEN cc = -(4294967295# - cc + 1)
- MD5AddModulo32& = CLNG( cc )
- END FUNCTION
- ' 31 23 15 s 7 0
- ' before: [hhhhhhhh][hhhhllll][llllllll][llllllll]
- ' after: [llllllll][llllllll][llllhhhh][hhhhhhhh]
- DEFLNG a-z
- FUNCTION MD5RotateLeft& ( n AS LONG, s AS INTEGER )
- DIM ss AS INTEGER : ss = s MOD 32
- IF ss <= 0 THEN MD5RotateLeft& = n : EXIT FUNCTION
- DIM highMask AS DOUBLE : highMask = (2# ^ ss - 1) * (2# ^ (32# - ss))
- DIM lowMask AS DOUBLE : lowMask = (2# ^ (32# - ss) - 1)
- ' unsigned to signed
- IF ( highMask > 2147483647# ) THEN highMask = -(4294967295# - highMask + 1)
- IF ( lowMask > 2147483647# ) THEN lowMask = -(4294967295# - lowMask + 1)
- DIM highBits AS DOUBLE : highBits = CDBL( n AND CLNG( highMask ) )
- DIM lowBits AS DOUBLE : lowBits = CDBL( n AND CLNG( lowMask ) )
- ' signed to unsigned
- IF ( highBits < 0 ) THEN highBits = 4294967295# + highBits + 1
- IF ( lowBits < 0 ) THEN lowBits = 4294967295# + lowBits + 1
- highBits = highBits / (2# ^ (32 - ss))
- lowBits = lowBits * (2# ^ ss)
- ' unsigned to signed
- IF ( highBits > 2147483647# ) THEN highBits = -(4294967295# - highBits + 1)
- IF ( lowBits > 2147483647# ) THEN lowBits = -(4294967295# - lowBits + 1)
- MD5RotateLeft& = CLNG( lowBits ) OR CLNG( highBits )
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5RoundF& ( x AS LONG, y AS LONG, z AS LONG )
- MD5RoundF& = (x AND y) OR ((NOT x) AND z)
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5RoundG& ( x AS LONG, y AS LONG, z AS LONG )
- MD5RoundG& = (x AND z) OR (y AND NOT z)
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5RoundH& ( x AS LONG, y AS LONG, z AS LONG )
- MD5RoundH& = x XOR y XOR z
- END FUNCTION
- DEFLNG a-z
- FUNCTION MD5RoundI& ( x AS LONG, y AS LONG, z AS LONG )
- MD5RoundI& = y XOR (x OR NOT z)
- END FUNCTION
- DEFLNG a-z
- SUB MD5FF ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DIM tmp AS LONG
- ' a = MD5RotateLeft&( ( a + MD5RoundF&( b, c, d ) + k + T ), s ) + b
- tmp = MD5AddModulo32&( a, MD5RoundF&( b, c, d ) )
- tmp = MD5AddModulo32&( tmp, k )
- tmp = MD5AddModulo32&( tmp, T )
- tmp = MD5RotateLeft&( tmp, s )
- a = MD5AddModulo32&( tmp, b )
- END SUB
- DEFLNG a-z
- SUB MD5GG ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DIM tmp AS LONG
- tmp = MD5AddModulo32&( a, MD5RoundG&( b, c, d ) )
- tmp = MD5AddModulo32&( tmp, k )
- tmp = MD5AddModulo32&( tmp, T )
- tmp = MD5RotateLeft&( tmp, s )
- a = MD5AddModulo32&( tmp, b )
- END SUB
- DEFLNG a-z
- SUB MD5HH ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DIM tmp AS LONG
- tmp = MD5AddModulo32&( a, MD5RoundH&( b, c, d ) )
- tmp = MD5AddModulo32&( tmp, k )
- tmp = MD5AddModulo32&( tmp, T )
- tmp = MD5RotateLeft&( tmp, s )
- a = MD5AddModulo32&( tmp, b )
- END SUB
- DEFLNG a-z
- SUB MD5II ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
- DIM tmp AS LONG
- tmp = MD5AddModulo32&( a, MD5RoundI&( b, c, d ) )
- tmp = MD5AddModulo32&( tmp, k )
- tmp = MD5AddModulo32&( tmp, T )
- tmp = MD5RotateLeft&( tmp, s )
- a = MD5AddModulo32&( tmp, b )
- END SUB
- DEFLNG a-z
- SUB MD5HashBlock ( state AS MD5HashState, blockPtr AS INTEGER )
- DIM X(0 TO 15) AS LONG
- ' The code
- ' MD5Decode varptr( X(0) ), blockPtr, 64
- ' doesn't work, so we do the following:
- FOR i = 0 TO 15
- DIM value AS DOUBLE
- value = PEEK( blockPtr + (i*4) )
- value = value + PEEK( blockPtr + (i*4) + 1 ) * 2# ^ 8#
- value = value + PEEK( blockPtr + (i*4) + 2 ) * 2# ^ 16#
- value = value + PEEK( blockPtr + (i*4) + 3 ) * 2# ^ 24#
- ' unsigned to signed
- IF ( value > 2147483647# ) THEN value = -(4294967295# - value + 1)
- X(i) = CLNG( value )
- NEXT i
- DIM a AS LONG : a = state.a
- DIM b AS LONG : b = state.b
- DIM c AS LONG : c = state.c
- DIM d AS LONG : d = state.d
- ' Round 1
- MD5FF a, b, c, d, X(0), 7, T1
- MD5FF d, a, b, c, X(1), 12, T2
- MD5FF c, d, a, b, X(2), 17, T3
- MD5FF b, c, d, a, X(3), 22, T4
- MD5FF a, b, c, d, X(4), 7, T5
- MD5FF d, a, b, c, X(5), 12, T6
- MD5FF c, d, a, b, X(6), 17, T7
- MD5FF b, c, d, a, X(7), 22, T8
- MD5FF a, b, c, d, X(8), 7, T9
- MD5FF d, a, b, c, X(9), 12, T10
- MD5FF c, d, a, b, X(10), 17, T11
- MD5FF b, c, d, a, X(11), 22, T12
- MD5FF a, b, c, d, X(12), 7, T13
- MD5FF d, a, b, c, X(13), 12, T14
- MD5FF c, d, a, b, X(14), 17, T15
- MD5FF b, c, d, a, X(15), 22, T16
- ' Round 2
- MD5GG a, b, c, d, X(1), 5, T17
- MD5GG d, a, b, c, X(6), 9, T18
- MD5GG c, d, a, b, X(11), 14, T19
- MD5GG b, c, d, a, X(0), 20, T20
- MD5GG a, b, c, d, X(5), 5, T21
- MD5GG d, a, b, c, X(10), 9, T22
- MD5GG c, d, a, b, X(15), 14, T23
- MD5GG b, c, d, a, X(4), 20, T24
- MD5GG a, b, c, d, X(9), 5, T25
- MD5GG d, a, b, c, X(14), 9, T26
- MD5GG c, d, a, b, X(3), 14, T27
- MD5GG b, c, d, a, X(8), 20, T28
- MD5GG a, b, c, d, X(13), 5, T29
- MD5GG d, a, b, c, X(2), 9, T30
- MD5GG c, d, a, b, X(7), 14, T31
- MD5GG b, c, d, a, X(12), 20, T32
- ' Round 3
- MD5HH a, b, c, d, X(5), 4, T33
- MD5HH d, a, b, c, X(8), 11, T34
- MD5HH c, d, a, b, X(11), 16, T35
- MD5HH b, c, d, a, X(14), 23, T36
- MD5HH a, b, c, d, X(1), 4, T37
- MD5HH d, a, b, c, X(4), 11, T38
- MD5HH c, d, a, b, X(7), 16, T39
- MD5HH b, c, d, a, X(10), 23, T40
- MD5HH a, b, c, d, X(13), 4, T41
- MD5HH d, a, b, c, X(0), 11, T42
- MD5HH c, d, a, b, X(3), 16, T43
- MD5HH b, c, d, a, X(6), 23, T44
- MD5HH a, b, c, d, X(9), 4, T45
- MD5HH d, a, b, c, X(12), 11, T46
- MD5HH c, d, a, b, X(15), 16, T47
- MD5HH b, c, d, a, X(2), 23, T48
- ' Round 4
- MD5II a, b, c, d, X(0), 6, T49
- MD5II d, a, b, c, X(7), 10, T50
- MD5II c, d, a, b, X(14), 15, T51
- MD5II b, c, d, a, X(5), 21, T52
- MD5II a, b, c, d, X(12), 6, T53
- MD5II d, a, b, c, X(3), 10, T54
- MD5II c, d, a, b, X(10), 15, T55
- MD5II b, c, d, a, X(1), 21, T56
- MD5II a, b, c, d, X(8), 6, T57
- MD5II d, a, b, c, X(15), 10, T58
- MD5II c, d, a, b, X(6), 15, T59
- MD5II b, c, d, a, X(13), 21, T60
- MD5II a, b, c, d, X(4), 6, T61
- MD5II d, a, b, c, X(11), 10, T62
- MD5II c, d, a, b, X(2), 15, T63
- MD5II b, c, d, a, X(9), 21, T64
- ' update the state.
- state.a = MD5AddModulo32&( state.a, a )
- state.b = MD5AddModulo32&( state.b, b )
- state.c = MD5AddModulo32&( state.c, c )
- state.d = MD5AddModulo32&( state.d, d )
- END SUB
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement