Advertisement
Guest User

QBasic MD5 by stylin

a guest
Dec 6th, 2018
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
QBasic 18.40 KB | None | 0 0
  1. ' http://forum.qbasicnews.com/index.php?topic=13371.0
  2.  
  3. ' MD5 Cryptographic Hash Function
  4. ' stylin
  5. ' on: November 01, 2009, 05:49:02 PM
  6.  
  7. ' 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.
  8.  
  9. ' 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.
  10.  
  11. '' PUBLIC API
  12.  
  13. '' function: MD5HashString$
  14. ''  Returns the 32-character hexadecimal string representation of the
  15. ''  message digest of `message`.
  16. DECLARE FUNCTION MD5HashString$ ( message AS STRING )
  17.  
  18. '' function: MD5HashFile$
  19. ''  Returns the 32-character hexadecimal string representation of the
  20. ''  message digest of the file `fileName`.
  21. DECLARE FUNCTION MD5HashFile$ ( fileName AS STRING )
  22.  
  23. '' type: MD5HashState
  24. ''  Stores the state of a hash operation. Use MD5Initialize, followed by calls
  25. ''  to MD5Update/MD5UpdateAux for all message bytes, then
  26. ''  MD5Finalize/MD5FinalizeAux to retrieve the message digest. (See
  27. ''  implementation for MD5HashFile$.) All fields are considered private.
  28. TYPE MD5HashState
  29.     bitCount AS LONG
  30.     bitCount2 AS LONG
  31.     a AS LONG
  32.     b AS LONG
  33.     c AS LONG
  34.     d AS LONG
  35.     block AS STRING * 64
  36. END TYPE
  37.  
  38. '' sub: MD5Initialize
  39. ''  Prepares `state` for calls to Update.
  40. DECLARE SUB MD5Initialize ( state AS MD5HashState )
  41.  
  42. '' sub: MD5Update
  43. ''  Begins or continues a hashing operation on `state` with the bytes in
  44. ''  `source`.
  45. DECLARE SUB MD5Update ( state AS MD5HashState, source AS STRING )
  46.  
  47. '' sub: MD5UpdateAux
  48. ''  Begins or continues a hashing operation on `state` with `sourceLength`
  49. ''  bytes starting at address `sourcePtr`.
  50. DECLARE SUB MD5UpdateAux ( state AS MD5HashState, sourcePtr AS INTEGER, sourceLength AS INTEGER )
  51.  
  52. '' sub: MD5Finalize
  53. ''  Finishes the hashing operation on `state`, allocating and placing the
  54. ''  16-byte message digest in `digest`.
  55. DECLARE SUB MD5Finalize ( state AS MD5HashState, digest AS STRING )
  56.  
  57. '' sub: MD5FinalizeAux
  58. ''  Finishes the hashing operation on `state`, placing the 16-byte message
  59. ''  digest in the pre-allocated memory starting at `digestPtr`.
  60. DECLARE SUB MD5FinalizeAux ( state AS MD5HashState, digestPtr AS INTEGER )
  61.  
  62. '' function: MD5GetHexFromBytes$
  63. ''  Returns the (2 * `srcLen`)-character hexadecimal string representation of
  64. ''  the bytes starting at `srcPtr`.
  65. DECLARE FUNCTION MD5GetHexFromBytes$ ( srcPtr AS INTEGER, srcLen AS INTEGER )
  66.  
  67. '' function: MD5GetStringDataPtr%
  68. ''  Helper to retrieve the near address of first character of variable-length
  69. ''  strings and string parameters.
  70. DECLARE FUNCTION MD5GetStringDataPtr% ( s AS STRING )
  71.  
  72. '' INTERNAL API
  73.  
  74. DECLARE SUB MD5HashBlock ( state AS MD5HashState, blockPtr AS INTEGER )
  75. DECLARE FUNCTION MD5RoundF& ( x AS LONG, y AS LONG, z AS LONG )
  76. DECLARE FUNCTION MD5RoundG& ( x AS LONG, y AS LONG, z AS LONG )
  77. DECLARE FUNCTION MD5RoundH& ( x AS LONG, y AS LONG, z AS LONG )
  78. DECLARE FUNCTION MD5RoundI& ( x AS LONG, y AS LONG, z AS LONG )
  79. DECLARE SUB MD5FF ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  80. DECLARE SUB MD5GG ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  81. DECLARE SUB MD5HH ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  82. DECLARE SUB MD5II ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  83. DECLARE FUNCTION MD5AddModulo32& ( a AS LONG, b AS LONG )
  84. DECLARE FUNCTION MD5RotateLeft& ( n AS LONG, s AS INTEGER )
  85. DECLARE SUB MD5MemCopy ( dstPtr AS INTEGER, srcPtr AS INTEGER, length AS INTEGER )
  86.  
  87.  
  88.         '' ::::: [demo code]
  89.  
  90.         ' d41d8cd98f00b204e9800998ecf8427e
  91.         PRINT MD5HashString$( "" )
  92.         ' 0cc175b9c0f1b6a831c399e269772661
  93.         PRINT MD5HashString$( "a" )
  94.         ' 900150983cd24fb0d6963f7d28e17f72
  95.         PRINT MD5HashString$( "abc" )
  96.         ' f96b697d7cb7938d525a2f31aaf161d0
  97.         PRINT MD5HashString$( "message digest" )
  98.         ' c3fcd3d76192e4007dfb496cca67e13b
  99.         PRINT MD5HashString$( "abcdefghijklmnopqrstuvwxyz" )
  100.         ' d174ab98d277d9f5a5611c2c9f419d9f
  101.         PRINT MD5HashString$( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" )
  102.         ' 57edf4a22be3c955ac49da2e2107b67a
  103.         PRINT MD5HashString$( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" )
  104.         END
  105.  
  106.         '' ::::: [/demo code]
  107.  
  108. DEFLNG a-z
  109. FUNCTION MD5HashString$ ( message AS STRING )
  110.  
  111.     DIM state AS MD5HashState
  112.     DIM digest AS STRING
  113.  
  114.     MD5Initialize state
  115.     MD5Update state, message
  116.     MD5Finalize state, digest
  117.  
  118.     MD5HashString$ = MD5GetHexFromBytes$( MD5GetStringDataPtr%( digest ), LEN( digest ) )
  119.  
  120. END FUNCTION
  121.  
  122. DEFLNG a-z
  123. FUNCTION MD5HashFile$ ( fileName AS STRING )
  124.  
  125.     DIM fileNum AS INTEGER : fileNum = FREEFILE
  126.     OPEN fileName FOR BINARY ACCESS READ AS #fileNum
  127.  
  128.     DIM state AS MD5HashState
  129.     MD5Initialize state
  130.  
  131.     DIM bytesLeft AS LONG : bytesLeft = LOF( fileNum )
  132.     DIM buffer AS STRING : buffer = SPACE$( 2048 )
  133.  
  134.     DO WHILE bytesLeft
  135.         IF ( bytesLeft < LEN( buffer ) ) THEN
  136.             buffer = SPACE$( bytesLeft )
  137.         END IF
  138.         GET #filenum, , buffer
  139.         bytesLeft = bytesLeft - LEN( buffer )
  140.         MD5Update state, buffer
  141.     LOOP
  142.     CLOSE #filenum
  143.  
  144.     DIM digest AS STRING
  145.     MD5Finalize state, digest
  146.  
  147.     MD5HashFile$ = MD5GetHexFromBytes$( MD5GetStringDataPtr%( digest ), LEN( digest ) )
  148.  
  149. END FUNCTION
  150.  
  151. DEFLNG a-z
  152. FUNCTION MD5GetHexFromBytes$ ( srcPtr AS INTEGER, srcLen AS INTEGER )
  153.  
  154.     DIM result AS STRING * 32
  155.     FOR i = 0 TO srcLen - 1
  156.         DIM b AS INTEGER : b = PEEK( srcPtr + i )
  157.         DIM highNibble AS INTEGER : highNibble = ( b AND &HF0 ) \ 16
  158.         DIM  lowNibble AS INTEGER :  lowNibble = ( b AND &H0F )
  159.         MID$( result, (i*2) + 1, 1 ) = HEX$( highNibble )
  160.         MID$( result, (i*2) + 2, 1 ) = HEX$( lowNibble )
  161.     NEXT i
  162.     MD5GetHexFromBytes$ = result
  163.  
  164. END FUNCTION
  165.  
  166. DEFLNG a-z
  167. SUB MD5Encode ( dstPtr AS INTEGER, srcPtr AS INTEGER, n AS INTEGER )
  168.     DIM i AS INTEGER
  169.     DIM j AS INTEGER
  170.  
  171.     DO WHILE j < n
  172.         POKE dstPtr + j    ,   PEEK( srcPtr + i + 0 )
  173.         POKE dstPtr + j + 1,   PEEK( srcPtr + i + 1 )
  174.         POKE dstPtr + j + 2,   PEEK( srcPtr + i + 2 )
  175.         POKE dstPtr + j + 3,   PEEK( srcPtr + i + 3 )
  176.         i = i + 4
  177.         j = j + 4
  178.     LOOP
  179. END SUB
  180.  
  181. DEFLNG a-z
  182. SUB MD5Decode ( dstPtr AS INTEGER, srcPtr AS INTEGER, n AS INTEGER )
  183.     DIM i AS INTEGER
  184.     DIM j AS INTEGER
  185.  
  186.     DO WHILE j < n
  187.         POKE dstPtr + j    ,   PEEK( srcPtr + i + 0 )
  188.         POKE dstPtr + j + 1,   PEEK( srcPtr + i + 1 )
  189.         POKE dstPtr + j + 2,   PEEK( srcPtr + i + 2 )
  190.         POKE dstPtr + j + 3,   PEEK( srcPtr + i + 3 )
  191.         i = i + 4
  192.         j = j + 4
  193.     LOOP
  194. END SUB
  195.  
  196. DEFLNG a-z
  197. SUB MD5Initialize ( state AS MD5HashState )
  198.     ' prime state variables with these magic numbers:
  199.     state.a = &h67452301
  200.     state.b = &hefcdab89
  201.     state.c = &h98badcfe
  202.     state.d = &h10325476
  203. END SUB
  204.  
  205. DEFLNG a-z
  206. SUB MD5Update ( state AS MD5HashState, bytes AS STRING )
  207.     MD5UpdateAux state, MD5GetStringDataPtr%( bytes ), LEN( bytes )
  208. END SUB
  209.  
  210. DEFLNG a-z
  211. SUB MD5UpdateAux ( state AS MD5HashState, srcPtr AS INTEGER, srcLen AS INTEGER )
  212.  
  213.     DIM index AS INTEGER
  214.     DIM partLen AS INTEGER
  215.     DIM i AS INTEGER
  216.  
  217.     index = ( state.bitCount \ 8 ) AND &H3f
  218.  
  219.     ' update bit count..
  220.     state.bitCount = MD5AddModulo32&( state.bitCount, srcLen * 8 )
  221.     IF ( state.bitCount < srcLen * 8 ) THEN
  222.         state.bitCount2 = state.bitCount2 + 1
  223.         state.bitCount2 = MD5AddModulo32&( state.bitCount2, ( srcLen / 2& ^ 29& ) )
  224.     END IF
  225.  
  226.     partLen = 64 - index
  227.     i = 0
  228.     IF ( srclen >= partlen ) THEN
  229.         ' fill and hash buffer.
  230.         MD5MemCopy VARPTR( state.block ) + index, srcPtr, partLen
  231.         MD5HashBlock state, VARPTR( state.block )
  232.  
  233.         ' hash as many full-sized source blocks as possible.
  234.         i = partlen
  235.         DO WHILE i + 63 < srcLen
  236.             MD5HashBlock state, srcPtr + i
  237.             i = i + 64
  238.         LOOP
  239.         index = 0
  240.     END IF
  241.     ' buffer remaining source.
  242.     MD5MemCopy VARPTR( state.block ) + index, srcPtr + i, srcLen - i
  243.  
  244. END SUB
  245.  
  246. DEFLNG a-z
  247. SUB MD5Finalize ( state AS MD5HashState, digest AS STRING )
  248.     digest = SPACE$( 16 )
  249.     MD5FinalizeAux state, MD5GetStringDataPtr%( digest )
  250. END SUB
  251.  
  252. DEFLNG a-z
  253. SUB MD5FinalizeAux ( state AS MD5HashState, digestPtr AS INTEGER )
  254.  
  255.     ' storage for arbitrary padding lengths:
  256.     DIM PADDING AS STRING * 64
  257.     MID$( PADDING, 1, 1 ) = CHR$( &H80 )
  258.  
  259.     DIM index AS INTEGER
  260.     DIM padLen AS INTEGER
  261.  
  262.     ' save bit count (up to padding bits)
  263.     DIM bitCountStorage AS STRING * 8
  264.     MD5Encode VARPTR( bitCountStorage ), VARPTR( state.bitCount ), 8
  265.  
  266.     ' 'append' and hash padding bytes (leaving 8 bytes for length).
  267.     index = ( state.bitCount \ 8 ) AND &H3f
  268.     IF ( index < 56 ) THEN
  269.         padLen = 56 - index
  270.     ELSE
  271.         padLen = 120 - index
  272.     END IF
  273.     MD5UpdateAux state, VARPTR( PADDING ), padLen
  274.  
  275.     ' 'append' and hash the message length.
  276.     MD5Update state, bitCountStorage
  277.  
  278.     ' state (abcd) now holds the final digest; MD5Encode to byte array.
  279.     MD5Encode digestPtr, VARPTR( state.a ), 16
  280.  
  281. END FUNCTION
  282.  
  283. DEFLNG a-z
  284. FUNCTION MD5GetStringDataPtr% ( s AS STRING )
  285.     DIM dataPtr AS DOUBLE
  286.     dataPtr =           PEEK( VARPTR( s ) + 2 )
  287.     dataPtr = dataPtr + PEEK( VARPTR( s ) + 3 ) * 256#
  288.     ' unsigned to signed
  289.     IF ( dataPtr > 32767# ) THEN dataPtr = -(65535# - dataPtr + 1)
  290.  
  291.     MD5GetStringDataPtr% = CINT( dataPtr )
  292.  
  293. END FUNCTION
  294.  
  295. DEFLNG a-z
  296. SUB MD5MemCopy ( dstPtr AS INTEGER, srcPtr AS INTEGER, length AS INTEGER )
  297.     FOR i = 0 TO length - 1
  298.         POKE dstPtr + i, PEEK( srcPtr + i )
  299.     NEXT i
  300. END SUB
  301.  
  302. DEFLNG a-z
  303.  
  304. CONST T1 = &hd76aa478
  305. CONST T2 = &he8c7b756
  306. CONST T3 = &h242070db
  307. CONST T4 = &hc1bdceee
  308. CONST T5 = &hf57c0faf
  309. CONST T6 = &h4787c62a
  310. CONST T7 = &ha8304613
  311. CONST T8 = &hfd469501
  312. CONST T9 = &h698098d8
  313. CONST T10 = &h8b44f7af
  314. CONST T11 = &hffff5bb1
  315. CONST T12 = &h895cd7be
  316. CONST T13 = &h6b901122
  317. CONST T14 = &hfd987193
  318. CONST T15 = &ha679438e
  319. CONST T16 = &h49b40821
  320. CONST T17 = &hf61e2562
  321. CONST T18 = &hc040b340
  322. CONST T19 = &h265e5a51
  323. CONST T20 = &he9b6c7aa
  324. CONST T21 = &hd62f105d
  325. CONST T22 = &h02441453
  326. CONST T23 = &hd8a1e681
  327. CONST T24 = &he7d3fbc8
  328. CONST T25 = &h21e1cde6
  329. CONST T26 = &hc33707d6
  330. CONST T27 = &hf4d50d87
  331. CONST T28 = &h455a14ed
  332. CONST T29 = &ha9e3e905
  333. CONST T30 = &hfcefa3f8
  334. CONST T31 = &h676f02d9
  335. CONST T32 = &h8d2a4c8a
  336. CONST T33 = &hfffa3942
  337. CONST T34 = &h8771f681
  338. CONST T35 = &h6d9d6122
  339. CONST T36 = &hfde5380c
  340. CONST T37 = &ha4beea44
  341. CONST T38 = &h4bdecfa9
  342. CONST T39 = &hf6bb4b60
  343. CONST T40 = &hbebfbc70
  344. CONST T41 = &h289b7ec6
  345. CONST T42 = &heaa127fa
  346. CONST T43 = &hd4ef3085
  347. CONST T44 = &h04881d05
  348. CONST T45 = &hd9d4d039
  349. CONST T46 = &he6db99e5
  350. CONST T47 = &h1fa27cf8
  351. CONST T48 = &hc4ac5665
  352. CONST T49 = &hf4292244
  353. CONST T50 = &h432aff97
  354. CONST T51 = &hab9423a7
  355. CONST T52 = &hfc93a039
  356. CONST T53 = &h655b59c3
  357. CONST T54 = &h8f0ccc92
  358. CONST T55 = &hffeff47d
  359. CONST T56 = &h85845dd1
  360. CONST T57 = &h6fa87e4f
  361. CONST T58 = &hfe2ce6e0
  362. CONST T59 = &ha3014314
  363. CONST T60 = &h4e0811a1
  364. CONST T61 = &hf7537e82
  365. CONST T62 = &hbd3af235
  366. CONST T63 = &h2ad7d2bb
  367. CONST T64 = &heb86d391
  368.  
  369. ' signed/unsigned conversions:
  370. '
  371. ' unsigned to signed:
  372. '  if( value > MAX_SIGNED_VALUE ) then
  373. '   value = -( MAX_UNSIGNED_VALUE - value + 1 )
  374. '  end if
  375. '
  376. ' signed to unsigned:
  377. '  if( value < 0 ) then
  378. '   value = MAX_UNSIGNED_VALUE + value + 1
  379. '  end if
  380.  
  381. ' The following is used instead of "a + b" where necessary to provide addition
  382. ' modulo 32-bit of unsigned integers; needed because
  383. '  1) QuickBASIC/QB throws an error on additive overflow, and
  384. '  2) QuickBASIC/QB has no unsigned integer types.
  385. DEFLNG a-z
  386. FUNCTION MD5AddModulo32& ( a AS LONG, b AS LONG )
  387.  
  388.     DIM aa AS DOUBLE : aa = CDBL( a )
  389.     DIM bb AS DOUBLE : bb = CDBL( b )
  390.  
  391.     ' signed to unsigned
  392.     IF ( a < 0 ) THEN aa = 4294967295# + a + 1
  393.     IF ( b < 0 ) THEN bb = 4294967295# + b + 1
  394.  
  395.     DIM cc AS DOUBLE : cc = aa + bb
  396.     ' keep 32-bit portion ( cc = cc and &hFFFFFFFF )
  397.     IF ( cc > 4294967295# ) THEN cc = cc - 4294967296#
  398.     ' unsigned to signed
  399.     IF ( cc > 2147483647# ) THEN cc = -(4294967295# - cc + 1)
  400.  
  401.     MD5AddModulo32& = CLNG( cc )
  402.  
  403. END FUNCTION
  404.  
  405. '          31        23        15 s      7      0
  406. ' before: [hhhhhhhh][hhhhllll][llllllll][llllllll]
  407. ' after:  [llllllll][llllllll][llllhhhh][hhhhhhhh]
  408. DEFLNG a-z
  409. FUNCTION MD5RotateLeft& ( n AS LONG, s AS INTEGER )
  410.     DIM ss AS INTEGER : ss = s MOD 32
  411.  
  412.     IF ss <= 0 THEN MD5RotateLeft& = n : EXIT FUNCTION
  413.  
  414.     DIM highMask AS DOUBLE : highMask = (2# ^ ss - 1) * (2# ^ (32# - ss))
  415.     DIM  lowMask AS DOUBLE :  lowMask = (2# ^ (32# - ss) - 1)
  416.     ' unsigned to signed
  417.     IF ( highMask > 2147483647# ) THEN highMask = -(4294967295# - highMask + 1)
  418.     IF (  lowMask > 2147483647# ) THEN  lowMask = -(4294967295# - lowMask + 1)
  419.  
  420.     DIM highBits AS DOUBLE : highBits = CDBL( n AND CLNG( highMask ) )
  421.     DIM  lowBits AS DOUBLE :  lowBits = CDBL( n AND CLNG( lowMask ) )
  422.     ' signed to unsigned
  423.     IF ( highBits < 0 ) THEN highBits = 4294967295# + highBits + 1
  424.     IF (  lowBits < 0 ) THEN  lowBits = 4294967295# + lowBits + 1
  425.  
  426.     highBits = highBits / (2# ^ (32 - ss))
  427.      lowBits =  lowBits * (2# ^ ss)
  428.     ' unsigned to signed
  429.     IF ( highBits > 2147483647# ) THEN highBits = -(4294967295# - highBits + 1)
  430.     IF (  lowBits > 2147483647# ) THEN  lowBits = -(4294967295# - lowBits + 1)
  431.  
  432.     MD5RotateLeft& = CLNG( lowBits ) OR CLNG( highBits )
  433.  
  434. END FUNCTION
  435.  
  436. DEFLNG a-z
  437. FUNCTION MD5RoundF& ( x AS LONG, y AS LONG, z AS LONG )
  438.     MD5RoundF& = (x AND y) OR ((NOT x) AND z)
  439. END FUNCTION
  440.  
  441. DEFLNG a-z
  442. FUNCTION MD5RoundG& ( x AS LONG, y AS LONG, z AS LONG )
  443.     MD5RoundG& = (x AND z) OR (y AND NOT z)
  444. END FUNCTION
  445.  
  446. DEFLNG a-z
  447. FUNCTION MD5RoundH& ( x AS LONG, y AS LONG, z AS LONG )
  448.     MD5RoundH& = x XOR y XOR z
  449. END FUNCTION
  450.  
  451. DEFLNG a-z
  452. FUNCTION MD5RoundI& ( x AS LONG, y AS LONG, z AS LONG )
  453.     MD5RoundI& = y XOR (x OR NOT z)
  454. END FUNCTION
  455.  
  456. DEFLNG a-z
  457. SUB MD5FF ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  458.     DIM tmp AS LONG
  459.  
  460.     ' a = MD5RotateLeft&( ( a + MD5RoundF&( b, c, d ) + k + T ), s ) + b
  461.     tmp = MD5AddModulo32&( a, MD5RoundF&( b, c, d ) )
  462.     tmp = MD5AddModulo32&( tmp, k )
  463.     tmp = MD5AddModulo32&( tmp, T )
  464.     tmp = MD5RotateLeft&( tmp, s )
  465.     a = MD5AddModulo32&( tmp, b )
  466.  
  467. END SUB
  468.  
  469. DEFLNG a-z
  470. SUB MD5GG ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  471.     DIM tmp AS LONG
  472.  
  473.     tmp = MD5AddModulo32&( a, MD5RoundG&( b, c, d ) )
  474.     tmp = MD5AddModulo32&( tmp, k )
  475.     tmp = MD5AddModulo32&( tmp, T )
  476.     tmp = MD5RotateLeft&( tmp, s )
  477.     a = MD5AddModulo32&( tmp, b )
  478. END SUB
  479.  
  480. DEFLNG a-z
  481. SUB MD5HH ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  482.     DIM tmp AS LONG
  483.  
  484.     tmp = MD5AddModulo32&( a, MD5RoundH&( b, c, d ) )
  485.     tmp = MD5AddModulo32&( tmp, k )
  486.     tmp = MD5AddModulo32&( tmp, T )
  487.     tmp = MD5RotateLeft&( tmp, s )
  488.     a = MD5AddModulo32&( tmp, b )
  489. END SUB
  490.  
  491. DEFLNG a-z
  492. SUB MD5II ( a AS LONG, b AS LONG, c AS LONG, d AS LONG, k AS LONG, s AS INTEGER, T AS LONG )
  493.     DIM tmp AS LONG
  494.  
  495.     tmp = MD5AddModulo32&( a, MD5RoundI&( b, c, d ) )
  496.     tmp = MD5AddModulo32&( tmp, k )
  497.     tmp = MD5AddModulo32&( tmp, T )
  498.     tmp = MD5RotateLeft&( tmp, s )
  499.     a = MD5AddModulo32&( tmp, b )
  500. END SUB
  501.  
  502. DEFLNG a-z
  503. SUB MD5HashBlock ( state AS MD5HashState, blockPtr AS INTEGER )
  504.  
  505.     DIM X(0 TO 15) AS LONG
  506.  
  507.     ' The code
  508.     '    MD5Decode varptr( X(0) ), blockPtr, 64
  509.     ' doesn't work, so we do the following:
  510.     FOR i = 0 TO 15
  511.         DIM value AS DOUBLE
  512.  
  513.         value =         PEEK( blockPtr + (i*4)     )
  514.         value = value + PEEK( blockPtr + (i*4) + 1 ) * 2# ^ 8#
  515.         value = value + PEEK( blockPtr + (i*4) + 2 ) * 2# ^ 16#
  516.         value = value + PEEK( blockPtr + (i*4) + 3 ) * 2# ^ 24#
  517.         ' unsigned to signed
  518.         IF ( value > 2147483647# ) THEN value = -(4294967295# - value + 1)
  519.  
  520.         X(i) = CLNG( value )
  521.     NEXT i
  522.  
  523.     DIM a AS LONG : a = state.a
  524.     DIM b AS LONG : b = state.b
  525.     DIM c AS LONG : c = state.c
  526.     DIM d AS LONG : d = state.d
  527.  
  528.     ' Round 1
  529.  
  530.     MD5FF a, b, c, d,  X(0),  7,  T1
  531.     MD5FF d, a, b, c,  X(1), 12,  T2
  532.     MD5FF c, d, a, b,  X(2), 17,  T3
  533.     MD5FF b, c, d, a,  X(3), 22,  T4
  534.     MD5FF a, b, c, d,  X(4),  7,  T5
  535.     MD5FF d, a, b, c,  X(5), 12,  T6
  536.     MD5FF c, d, a, b,  X(6), 17,  T7
  537.     MD5FF b, c, d, a,  X(7), 22,  T8
  538.     MD5FF a, b, c, d,  X(8),  7,  T9
  539.     MD5FF d, a, b, c,  X(9), 12, T10
  540.     MD5FF c, d, a, b, X(10), 17, T11
  541.     MD5FF b, c, d, a, X(11), 22, T12
  542.     MD5FF a, b, c, d, X(12),  7, T13
  543.     MD5FF d, a, b, c, X(13), 12, T14
  544.     MD5FF c, d, a, b, X(14), 17, T15
  545.     MD5FF b, c, d, a, X(15), 22, T16
  546.  
  547.  
  548.     ' Round 2
  549.     MD5GG a, b, c, d,  X(1),  5, T17
  550.     MD5GG d, a, b, c,  X(6),  9, T18
  551.     MD5GG c, d, a, b, X(11), 14, T19
  552.     MD5GG b, c, d, a,  X(0), 20, T20
  553.     MD5GG a, b, c, d,  X(5),  5, T21
  554.     MD5GG d, a, b, c, X(10),  9, T22
  555.     MD5GG c, d, a, b, X(15), 14, T23
  556.     MD5GG b, c, d, a,  X(4), 20, T24
  557.     MD5GG a, b, c, d,  X(9),  5, T25
  558.     MD5GG d, a, b, c, X(14),  9, T26
  559.     MD5GG c, d, a, b,  X(3), 14, T27
  560.     MD5GG b, c, d, a,  X(8), 20, T28
  561.     MD5GG a, b, c, d, X(13),  5, T29
  562.     MD5GG d, a, b, c,  X(2),  9, T30
  563.     MD5GG c, d, a, b,  X(7), 14, T31
  564.     MD5GG b, c, d, a, X(12), 20, T32
  565.  
  566.  
  567.     ' Round 3
  568.     MD5HH a, b, c, d,  X(5),  4, T33
  569.     MD5HH d, a, b, c,  X(8), 11, T34
  570.     MD5HH c, d, a, b, X(11), 16, T35
  571.     MD5HH b, c, d, a, X(14), 23, T36
  572.     MD5HH a, b, c, d,  X(1),  4, T37
  573.     MD5HH d, a, b, c,  X(4), 11, T38
  574.     MD5HH c, d, a, b,  X(7), 16, T39
  575.     MD5HH b, c, d, a, X(10), 23, T40
  576.     MD5HH a, b, c, d, X(13),  4, T41
  577.     MD5HH d, a, b, c,  X(0), 11, T42
  578.     MD5HH c, d, a, b,  X(3), 16, T43
  579.     MD5HH b, c, d, a,  X(6), 23, T44
  580.     MD5HH a, b, c, d,  X(9),  4, T45
  581.     MD5HH d, a, b, c, X(12), 11, T46
  582.     MD5HH c, d, a, b, X(15), 16, T47
  583.     MD5HH b, c, d, a,  X(2), 23, T48
  584.  
  585.     ' Round 4
  586.     MD5II a, b, c, d,  X(0),  6, T49
  587.     MD5II d, a, b, c,  X(7), 10, T50
  588.     MD5II c, d, a, b, X(14), 15, T51
  589.     MD5II b, c, d, a,  X(5), 21, T52
  590.     MD5II a, b, c, d, X(12),  6, T53
  591.     MD5II d, a, b, c,  X(3), 10, T54
  592.     MD5II c, d, a, b, X(10), 15, T55
  593.     MD5II b, c, d, a,  X(1), 21, T56
  594.     MD5II a, b, c, d,  X(8),  6, T57
  595.     MD5II d, a, b, c, X(15), 10, T58
  596.     MD5II c, d, a, b,  X(6), 15, T59
  597.     MD5II b, c, d, a, X(13), 21, T60
  598.     MD5II a, b, c, d,  X(4),  6, T61
  599.     MD5II d, a, b, c, X(11), 10, T62
  600.     MD5II c, d, a, b,  X(2), 15, T63
  601.     MD5II b, c, d, a,  X(9), 21, T64
  602.  
  603.     ' update the state.
  604.     state.a = MD5AddModulo32&( state.a, a )
  605.     state.b = MD5AddModulo32&( state.b, b )
  606.     state.c = MD5AddModulo32&( state.c, c )
  607.     state.d = MD5AddModulo32&( state.d, d )
  608.  
  609. END SUB
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement