Author Topic: Anyone got a hashing function?  (Read 3077 times)

0 Members and 1 Guest are viewing this topic.

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Anyone got a hashing function?
« on: July 16, 2020, 09:33:11 am »
I need to take blocks of text and produce an MD5/SHA1 hash - I actually don't really care about what algorithm it is, I'm just using it for giving unique names for things.

I'd write my own but I'm lazy and I figure one of you would have one on hand.

FellippeHeitor

  • Guest
Re: Anyone got a hashing function?
« Reply #1 on: July 16, 2020, 10:05:22 am »
Code: QB64: [Select]
  1. FUNCTION getChecksum$ (File$)
  2.     DIM fileHandle AS LONG
  3.  
  4.     IF _FILEEXISTS(File$) = 0 THEN EXIT SUB
  5.  
  6.     fileHandle = FREEFILE
  7.     OPEN File$ FOR BINARY AS fileHandle
  8.     DataArray$ = SPACE$(LOF(fileHandle))
  9.     GET #fileHandle, 1, DataArray$
  10.     CLOSE #fileHandle
  11.  
  12.     getChecksum$ = HEX$(crc32~&(DataArray$))
  13.  
  14. FUNCTION crc32~& (buf AS STRING)
  15.     'adapted from https://rosettacode.org/wiki/CRC-32
  16.     STATIC table(255) AS _UNSIGNED LONG
  17.     STATIC have_table AS _BYTE
  18.     DIM i AS LONG, j AS LONG
  19.  
  20.     IF have_table = 0 THEN
  21.         FOR i = 0 TO 255
  22.             k = i
  23.             FOR j = 0 TO 7
  24.                 IF (k AND 1) THEN
  25.                     k = _SHR(k, 1)
  26.                     k = k XOR &HEDB88320
  27.                 ELSE
  28.                     k = _SHR(k, 1)
  29.                 END IF
  30.                 table(i) = k
  31.             NEXT
  32.         NEXT
  33.         have_table = -1
  34.     END IF
  35.  
  36.     crc = NOT crc ' crc = &Hffffffff
  37.  
  38.     FOR i = 1 TO LEN(buf)
  39.         crc = (_SHR(crc, 8)) XOR table((crc AND &HFF) XOR ASC(buf, i))
  40.     NEXT
  41.  
  42.     crc32~& = NOT crc
« Last Edit: July 16, 2020, 10:07:30 am by FellippeHeitor »

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: Anyone got a hashing function?
« Reply #2 on: July 16, 2020, 10:07:50 am »
Hi Luke,
get my libraries collection from the Bonus Stuff Section here (link in signature below), it has both MD5 and SHA2 and has functions for string and file hashing. The algorithms are actually the ones used in Notepad++, hence it can consider they are well tested and reliable.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Anyone got a hashing function?
« Reply #3 on: July 16, 2020, 01:31:24 pm »
I remember codeguy posting one on the old site a couple years ago. I did a quick search and it's still up, today at least...
<url removed>

Code: QB64: [Select]
  1. ' This is sha160 and sha256 implemented in pure QB64 with no declare library.
  2. ' This is not intended to be efficient. It is very slow.
  3. ' It is meant more as a fun and perhaps informative demonstration than as a
  4. ' serious library.
  5. ' It is a loose translation of:
  6. ' http://www.network54.com/Forum/613583/message/1351232518/
  7. ' however, without the wildcard capability, and without the file times.
  8.  
  9.  
  10. DIM SHARED PowerOfTwo(0 TO 31) AS _UNSIGNED LONG
  11. '* Precalculate the powers of 2 rather than calculating every time. Exponentiation = CPU cycle hog.
  12. PowerOfTwo(0) = 1
  13. FOR p = 1 TO UBOUND(PowerOfTwo)
  14.     PowerOfTwo(p) = PowerOfTwo(p - 1) * 2
  15. DIM b AS STRING * 1
  16. cmd$ = "256 SHA256MCalkins.bas"
  17. x = INSTR(cmd$, " ")
  18. IF 0 = x THEN usage: SYSTEM
  19. y = VAL(LEFT$(cmd$, x - 1))
  20.     CASE 160, 256: setmode y
  21.     CASE ELSE: usage: PRINT "error on 1st parameter.": _DELAY 3: SYSTEM
  22.  
  23. IF _FILEEXISTS(MID$(cmd$, x + 1)) THEN
  24.     s# = TIMER(.001)
  25.     OPEN MID$(cmd$, x + 1) FOR BINARY ACCESS READ AS 1
  26.     filesize = LOF(1)
  27.     resethash
  28.     remaining = filesize
  29.     WHILE remaining >= 64
  30.         remaining = remaining - 64
  31.         GET 1, , M
  32.         nextchunk
  33.     WEND
  34.     IF remaining THEN
  35.         FOR t = 1 TO remaining
  36.             GET 1, , b
  37.             MID$(M, t, 1) = b
  38.         NEXT
  39.     END IF
  40.     finalchunk filesize
  41.     PRINT hexq(filesize); "  "; gethex; "  "; MID$(cmd$, x + 1)
  42.     CLOSE 1
  43.     e# = TIMER(.001)
  44.     PRINT e# - s#;
  45.     _DELAY 5
  46.     SYSTEM
  47.     usage: PRINT "error on 2nd parameter. File not found.": _DELAY 3: SYSTEM
  48.  
  49. SUB usage
  50. PRINT "Expirimental file hasher (pure qb64 version). Revision 2012 10 26"
  51. PRINT "Public domain, Michael Calkins."
  52. PRINT "160 and 256 bit hashes derived from fips180-3_final.pdf"
  53. PRINT "usage:"
  54. PRINT "", "sha {160 | 256} filename"
  55.  
  56. SUB setmode (m AS LONG)
  57.     CASE 160
  58.     CASE 256
  59.         K(0) = &H428A2F98: K(1) = &H71374491: K(2) = &HB5C0FBCF: K(3) = &HE9B5DBA5: K(4) = &H3956C25B: K(5) = &H59F111F1: K(6) = &H923F82A4: K(7) = &HAB1C5ED5
  60.         K(8) = &HD807AA98: K(9) = &H12835B01: K(10) = &H243185BE: K(11) = &H550C7DC3: K(12) = &H72BE5D74: K(13) = &H80DEB1FE: K(14) = &H9BDC06A7: K(15) = &HC19BF174
  61.         K(16) = &HE49B69C1: K(17) = &HEFBE4786: K(18) = &H0FC19DC6: K(19) = &H240CA1CC: K(20) = &H2DE92C6F: K(21) = &H4A7484AA: K(22) = &H5CB0A9DC: K(23) = &H76F988DA
  62.         K(24) = &H983E5152: K(25) = &HA831C66D: K(26) = &HB00327C8: K(27) = &HBF597FC7: K(28) = &HC6E00BF3: K(29) = &HD5A79147: K(30) = &H06CA6351: K(31) = &H14292967
  63.         K(32) = &H27B70A85: K(33) = &H2E1B2138: K(34) = &H4D2C6DFC: K(35) = &H53380D13: K(36) = &H650A7354: K(37) = &H766A0ABB: K(38) = &H81C2C92E: K(39) = &H92722C85
  64.         K(40) = &HA2BFE8A1: K(41) = &HA81A664B: K(42) = &HC24B8B70: K(43) = &HC76C51A3: K(44) = &HD192E819: K(45) = &HD6990624: K(46) = &HF40E3585: K(47) = &H106AA070
  65.         K(48) = &H19A4C116: K(49) = &H1E376C08: K(50) = &H2748774C: K(51) = &H34B0BCB5: K(52) = &H391C0CB3: K(53) = &H4ED8AA4A: K(54) = &H5B9CCA4F: K(55) = &H682E6FF3
  66.         K(56) = &H748F82EE: K(57) = &H78A5636F: K(58) = &H84C87814: K(59) = &H8CC70208: K(60) = &H90BEFFFA: K(61) = &HA4506CEB: K(62) = &HBEF9A3F7: K(63) = &HC67178F2
  67.     CASE ELSE
  68.         PRINT "bad mode": END
  69. mode = m
  70.  
  71. shl = x * PowerOfTwo(n)
  72.  
  73. shr = x \ PowerOfTwo(n)
  74.  
  75. shlq = x * PowerOfTwo(n)
  76.  
  77. shrq = x \ PowerOfTwo(n)
  78.  
  79. rol = shl(x, n) OR shr(x, 32 - n)
  80.  
  81. ror = shr(x, n) OR shl(x, 32 - n)
  82.  
  83. Ch = x AND y XOR NOT x AND z
  84.  
  85. Parity = x XOR y XOR z
  86.  
  87. Maj = x AND y XOR x AND z XOR y AND z
  88.  
  89. sum0 = ror(x, 2) XOR ror(x, 13) XOR ror(x, 22)
  90.  
  91. sum1 = ror(x, 6) XOR ror(x, 11) XOR ror(x, 25)
  92.  
  93. sel0 = ror(x, 7) XOR ror(x, 18) XOR shr(x, 3)
  94.  
  95. sel1 = ror(x, 17) XOR ror(x, 19) XOR shr(x, 10)
  96.  
  97. SUB resethash
  98.     CASE 160
  99.         H(0) = &H67452301: H(1) = &HEFCDAB89: H(2) = &H98BADCFE: H(3) = &H10325476: H(4) = &HC3D2E1F0
  100.     CASE 256
  101.         H(0) = &H6A09E667: H(1) = &HBB67AE85: H(2) = &H3C6EF372: H(3) = &HA54FF53A: H(4) = &H510E527F: H(5) = &H9B05688C: H(6) = &H1F83D9AB: H(7) = &H5BE0CD19
  102.  
  103. SUB nextchunk
  104. FOR t = 0 TO 63
  105.     W(t \ 4) = shl(W(t \ 4), 8) OR ASC(M, 1 + t)
  106.     CASE 160: hash160
  107.     CASE 256: hash256
  108.  
  109. SUB finalchunk (l AS _UNSIGNED _INTEGER64)
  110. FOR t = 0 TO (l AND &H3F) - 1
  111.     W(t \ 4) = shl(W(t \ 4), 8) OR ASC(M, 1 + t)
  112. W(t \ 4) = shl(W(t \ 4), 8) OR &H80
  113. t = t + 1
  114.  
  115.     W(t \ 4) = shl(W(t \ 4), 8)
  116.     t = t + 1
  117.  
  118. IF t >= 60 THEN
  119.     IF t = 60 THEN W(15) = 0
  120.     SELECT CASE mode
  121.         CASE 160: hash160
  122.         CASE 256: hash256
  123.     END SELECT
  124.     t = 0
  125.     t = shr(t, 2)
  126.  
  127. WHILE t < 14
  128.     W(t) = 0
  129.     t = t + 1
  130. W(14) = shrq(l, 29)
  131. W(15) = shlq(l, 3)
  132.     CASE 160: hash160
  133.     CASE 256: hash256
  134.  
  135. SUB hash160
  136.  
  137. FOR t = 16 TO 79
  138.     W(t) = rol(W(t - 3) XOR W(t - 8) XOR W(t - 14) XOR W(t - 16), 1)
  139.  
  140. a = H(0): b = H(1): c = H(2): d = H(3): e = H(4)
  141.  
  142. FOR t = 0 TO 19
  143.     Te = rol(a, 5) + Ch(b, c, d) + e + &H5A827999 + W(t)
  144.     e = d: d = c: c = rol(b, 30): b = a: a = Te
  145.  
  146. FOR t = 20 TO 39
  147.     Te = rol(a, 5) + Parity(b, c, d) + e + &H6ED9EBA1 + W(t)
  148.     e = d: d = c: c = rol(b, 30): b = a: a = Te
  149.  
  150. FOR t = 40 TO 59
  151.     Te = rol(a, 5) + Maj(b, c, d) + e + &H8F1BBCDC + W(t)
  152.     e = d: d = c: c = rol(b, 30): b = a: a = Te
  153.  
  154. FOR t = 60 TO 79
  155.     Te = rol(a, 5) + Parity(b, c, d) + e + &HCA62C1D6 + W(t)
  156.     e = d: d = c: c = rol(b, 30): b = a: a = Te
  157.  
  158. H(0) = H(0) + a: H(1) = H(1) + b: H(2) = H(2) + c: H(3) = H(3) + d: H(4) = H(4) + e
  159.  
  160. SUB hash256
  161.  
  162. FOR t = 16 TO 63
  163.     W(t) = sel1(W(t - 2)) + W(t - 7) + sel0(W(t - 15)) + W(t - 16)
  164.  
  165. a = H(0): b = H(1): c = H(2): d = H(3): e = H(4): f = H(5): g = H(6): hh = H(7)
  166.  
  167. FOR t = 0 TO 63
  168.     T1 = hh + sum1(e) + Ch(e, f, g) + K(t) + W(t)
  169.     T2 = sum0(a) + Maj(a, b, c)
  170.     hh = g: g = f: f = e: e = d + T1: d = c: c = b: b = a: a = T1 + T2
  171.  
  172. H(0) = H(0) + a: H(1) = H(1) + b: H(2) = H(2) + c: H(3) = H(3) + d: H(4) = H(4) + e: H(5) = H(5) + f: H(6) = H(6) + g: H(7) = H(7) + hh
  173.  
  174. FUNCTION gethex$
  175. t = ""
  176. FOR i = 0 TO mode \ 32 - 1
  177.     t = t + hexd(H(i))
  178. gethex = t
  179.  
  180. t = LCASE$(HEX$(n))
  181. hexq = STRING$(16 - LEN(t), &H30) + t
  182.  
  183. t = LCASE$(HEX$(n))
  184. hexd = STRING$(8 - LEN(t), &H30) + t

Code: QB64: [Select]
  1.  
  2.  
  3. DIM b AS STRING * 1
  4.  
  5. x = INSTR(COMMAND$, " ")
  6. IF 0 = x THEN usage: SYSTEM
  7. y = VAL(LEFT$(COMMAND$, x - 1))
  8.  CASE 160, 256: setmode y
  9.  CASE ELSE: usage: PRINT "error on 1st parameter.": SYSTEM
  10.  
  11. IF 0 = _FILEEXISTS(MID$(COMMAND$, x + 1)) THEN usage: PRINT "error on 2nd parameter. File not found.": SYSTEM
  12. filesize = LOF(1)
  13. resethash
  14. FOR remaining = filesize TO 64 STEP -64
  15.  GET 1, , M
  16.  nextchunk
  17. IF remaining THEN
  18.  FOR t = 1 TO remaining
  19.   GET 1, , b
  20.   MID$(M, t, 1) = b
  21. finalchunk filesize
  22. PRINT hexq(filesize); "  "; gethex; "  "; MID$(COMMAND$, x + 1)
  23.  
  24. SUB usage
  25. PRINT "Expirimental file hasher (pure qb64 version). Revision 2017 11 01"
  26. PRINT "speed expiriment using hardcoded rotate functions for 160."
  27. PRINT "Public domain, Michael Calkins."
  28. PRINT "160 and 256 bit hashes derived from fips180-3_final.pdf"
  29. PRINT "usage:"
  30. PRINT "", "sha {160 | 256} filename"
  31.  
  32. SUB setmode (m AS LONG)
  33.  CASE 160
  34.  CASE 256
  35.   K(0) = &H428A2F98: K(1) = &H71374491: K(2) = &HB5C0FBCF: K(3) = &HE9B5DBA5: K(4) = &H3956C25B: K(5) = &H59F111F1: K(6) = &H923F82A4: K(7) = &HAB1C5ED5
  36.   K(8) = &HD807AA98: K(9) = &H12835B01: K(10) = &H243185BE: K(11) = &H550C7DC3: K(12) = &H72BE5D74: K(13) = &H80DEB1FE: K(14) = &H9BDC06A7: K(15) = &HC19BF174
  37.   K(16) = &HE49B69C1: K(17) = &HEFBE4786: K(18) = &H0FC19DC6: K(19) = &H240CA1CC: K(20) = &H2DE92C6F: K(21) = &H4A7484AA: K(22) = &H5CB0A9DC: K(23) = &H76F988DA
  38.   K(24) = &H983E5152: K(25) = &HA831C66D: K(26) = &HB00327C8: K(27) = &HBF597FC7: K(28) = &HC6E00BF3: K(29) = &HD5A79147: K(30) = &H06CA6351: K(31) = &H14292967
  39.   K(32) = &H27B70A85: K(33) = &H2E1B2138: K(34) = &H4D2C6DFC: K(35) = &H53380D13: K(36) = &H650A7354: K(37) = &H766A0ABB: K(38) = &H81C2C92E: K(39) = &H92722C85
  40.   K(40) = &HA2BFE8A1: K(41) = &HA81A664B: K(42) = &HC24B8B70: K(43) = &HC76C51A3: K(44) = &HD192E819: K(45) = &HD6990624: K(46) = &HF40E3585: K(47) = &H106AA070
  41.   K(48) = &H19A4C116: K(49) = &H1E376C08: K(50) = &H2748774C: K(51) = &H34B0BCB5: K(52) = &H391C0CB3: K(53) = &H4ED8AA4A: K(54) = &H5B9CCA4F: K(55) = &H682E6FF3
  42.   K(56) = &H748F82EE: K(57) = &H78A5636F: K(58) = &H84C87814: K(59) = &H8CC70208: K(60) = &H90BEFFFA: K(61) = &HA4506CEB: K(62) = &HBEF9A3F7: K(63) = &HC67178F2
  43.   PRINT "bad mode": END
  44. mode = m
  45.  
  46. shl = x * 2 ^ n
  47.  
  48. shl8 = x * 256
  49.  
  50. shr = x \ 2 ^ n
  51.  
  52. shlq = x * 2 ^ n
  53.  
  54. shrq = x \ 2 ^ n
  55.  
  56. rol = shl(x, n) OR shr(x, 32 - n)
  57.  
  58. rol1 = x + x OR x \ &H80000000&
  59.  
  60. rol5 = x * 32 OR x \ &H8000000
  61.  
  62. rol30 = x * &H40000000 OR x \ 4
  63.  
  64. ror = shr(x, n) OR shl(x, 32 - n)
  65.  
  66. Ch = x AND y XOR NOT x AND z
  67.  
  68. Parity = x XOR y XOR z
  69.  
  70. Maj = x AND y XOR x AND z XOR y AND z
  71.  
  72. sum0 = ror(x, 2) XOR ror(x, 13) XOR ror(x, 22)
  73.  
  74. sum1 = ror(x, 6) XOR ror(x, 11) XOR ror(x, 25)
  75.  
  76. sel0 = ror(x, 7) XOR ror(x, 18) XOR shr(x, 3)
  77.  
  78. sel1 = ror(x, 17) XOR ror(x, 19) XOR shr(x, 10)
  79.  
  80. SUB resethash
  81.  CASE 160
  82.   H(0) = &H67452301: H(1) = &HEFCDAB89: H(2) = &H98BADCFE: H(3) = &H10325476: H(4) = &HC3D2E1F0
  83.  CASE 256
  84.   H(0) = &H6A09E667: H(1) = &HBB67AE85: H(2) = &H3C6EF372: H(3) = &HA54FF53A: H(4) = &H510E527F: H(5) = &H9B05688C: H(6) = &H1F83D9AB: H(7) = &H5BE0CD19
  85.  
  86. SUB nextchunk
  87. FOR t = 0 TO 63
  88.  W(t \ 4) = shl8(W(t \ 4)) OR ASC(M, 1 + t)
  89.  CASE 160: hash160
  90.  CASE 256: hash256
  91.  
  92. SUB finalchunk (l AS _UNSIGNED _INTEGER64)
  93. FOR t = 0 TO (l AND &H3F) - 1
  94.  W(t \ 4) = shl8(W(t \ 4)) OR ASC(M, 1 + t)
  95. W(t \ 4) = shl8(W(t \ 4)) OR &H80
  96. t = t + 1
  97.  
  98.  W(t \ 4) = shl8(W(t \ 4))
  99.  t = t + 1
  100.  
  101. IF t >= 60 THEN
  102.  IF t = 60 THEN W(15) = 0
  103.  SELECT CASE mode
  104.   CASE 160: hash160
  105.   CASE 256: hash256
  106.  t = 0
  107.  t = shr(t, 2)
  108.  
  109. WHILE t < 14
  110.  W(t) = 0
  111.  t = t + 1
  112. W(14) = shrq(l, 29)
  113. W(15) = shlq(l, 3)
  114.  CASE 160: hash160
  115.  CASE 256: hash256
  116.  
  117. SUB hash160
  118.  
  119. FOR t = 16 TO 79
  120.  W(t) = rol1(W(t - 3) XOR W(t - 8) XOR W(t - 14) XOR W(t - 16))
  121.  
  122. a = H(0): b = H(1): c = H(2): d = H(3): e = H(4)
  123.  
  124. FOR t = 0 TO 19
  125.  Te = rol5(a) + Ch(b, c, d) + e + &H5A827999 + W(t)
  126.  e = d: d = c: c = rol30(b): b = a: a = Te
  127.  
  128. FOR t = 20 TO 39
  129.  Te = rol5(a) + Parity(b, c, d) + e + &H6ED9EBA1 + W(t)
  130.  e = d: d = c: c = rol30(b): b = a: a = Te
  131.  
  132. FOR t = 40 TO 59
  133.  Te = rol5(a) + Maj(b, c, d) + e + &H8F1BBCDC + W(t)
  134.  e = d: d = c: c = rol30(b): b = a: a = Te
  135.  
  136. FOR t = 60 TO 79
  137.  Te = rol5(a) + Parity(b, c, d) + e + &HCA62C1D6 + W(t)
  138.  e = d: d = c: c = rol30(b): b = a: a = Te
  139.  
  140. H(0) = H(0) + a: H(1) = H(1) + b: H(2) = H(2) + c: H(3) = H(3) + d: H(4) = H(4) + e
  141.  
  142. SUB hash256
  143.  
  144. FOR t = 16 TO 63
  145.  W(t) = sel1(W(t - 2)) + W(t - 7) + sel0(W(t - 15)) + W(t - 16)
  146.  
  147. a = H(0): b = H(1): c = H(2): d = H(3): e = H(4): f = H(5): g = H(6): hh = H(7)
  148.  
  149. FOR t = 0 TO 63
  150.  T1 = hh + sum1(e) + Ch(e, f, g) + K(t) + W(t)
  151.  T2 = sum0(a) + Maj(a, b, c)
  152.  hh = g: g = f: f = e: e = d + T1: d = c: c = b: b = a: a = T1 + T2
  153.  
  154. H(0) = H(0) + a: H(1) = H(1) + b: H(2) = H(2) + c: H(3) = H(3) + d: H(4) = H(4) + e: H(5) = H(5) + f: H(6) = H(6) + g: H(7) = H(7) + hh
  155.  
  156. FUNCTION gethex$
  157. t = ""
  158. FOR i = 0 TO mode \ 32 - 1
  159.  t = t + hexd(H(i))
  160. gethex = t
  161.  
  162. t = LCASE$(HEX$(n))
  163. hexq = STRING$(16 - LEN(t), &H30) + t
  164.  
  165. t = LCASE$(HEX$(n))
  166. hexd = STRING$(8 - LEN(t), &H30) + t

- Dav
« Last Edit: July 16, 2020, 01:57:32 pm by odin »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Anyone got a hashing function?
« Reply #4 on: July 16, 2020, 03:29:48 pm »
Here is one written by one the best QBasic programmers.
source: https://www.tapatalk.com/groups/qbasic/programlist-artelius-t30556.html

Code: QB64: [Select]
  1. DECLARE FUNCTION leftrotate& (A AS LONG, B AS INTEGER)
  2.  
  3. 'Demo
  4. PRINT MD5("")
  5.  
  6. FUNCTION add& (A AS LONG, B AS LONG)
  7. C = (A AND &HFFFFFF) + (B AND &HFFFFFF)
  8. POKE VARPTR(C) + 3, PEEK(VARPTR(A) + 3) + PEEK(VARPTR(B) + 3) - (C > &HFFFFFF)
  9. add = C
  10.  
  11. 'Remove LCASE$ if you want uppercase hex
  12. FUNCTION hexp$ (A AS LONG)
  13. FOR I = 0 TO 3
  14. T = T + RIGHT$(LCASE$(HEX$(256 + PEEK(VARPTR(A) + I))), 2)
  15. hexp = T
  16.  
  17. FUNCTION leftrotate& (A AS LONG, B AS INTEGER)
  18. C = A
  19. FOR I = 1 TO B
  20. C = add(C, C)
  21. leftrotate = C OR (((A AND &H7FFFFFFF) \ 2 OR (A < 0) AND &H40000000) \ (2 ^ (31 - B)))
  22.  
  23. FUNCTION MD5$ (in AS STRING)
  24. STATIC init AS INTEGER, r() AS INTEGER, Garbage() AS LONG
  25.  
  26. DIM h0 AS LONG, h1 AS LONG, h2 AS LONG, h3 AS LONG
  27. DIM A AS LONG, B AS LONG, C AS LONG, D AS LONG
  28. DIM F AS LONG, G AS LONG, temp AS LONG
  29. DIM mess(0 TO 15) AS LONG
  30.  
  31. IF init = 0 THEN
  32. REDIM r(0 TO 63) AS INTEGER, Garbage(0 TO 63) AS LONG
  33. r(0) = 7: r(1) = 12: r(2) = 17: r(3) = 22
  34. r(4) = 5: r(5) = 9: r(6) = 14: r(7) = 20
  35. r(8) = 4: r(9) = 11: r(10) = 16: r(11) = 23
  36. r(12) = 6: r(13) = 10: r(14) = 15: r(15) = 21
  37.  
  38. FOR I = 63 TO 4 STEP -1
  39. r(I) = r((I AND 3) OR ((I AND 48) \ 4))
  40.  
  41. FOR I = 0 TO 63
  42. dtemp = ABS(SIN(CDBL(I + 1))) * 4294967296#
  43. IF dtemp >= 2147483648# THEN dtemp = dtemp - 4294967296#
  44. Garbage(I) = INT(dtemp)
  45. init = 1
  46.  
  47.  
  48. h0 = &H67452301
  49. h1 = &HEFCDAB89
  50. h2 = &H98BADCFE
  51. h3 = &H10325476
  52.  
  53. in = in + CHR$(128) + STRING$((55 - LEN(in) AND 63), 0) + CHR$((LEN(in) * 8) AND 255) + CHR$(LEN(in) \ 32) + STRING$(6, 0)
  54.  
  55. FOR I = 0 TO LEN(in) - 1 STEP 64
  56. FOR J = 0 TO 15
  57. mess(J) = CVL(MID$(in, J * 4 + I + 1, 4))
  58. A = h0
  59. B = h1
  60. C = h2
  61. D = h3
  62. FOR J = 0 TO 15
  63. F = ((C XOR D) AND B) XOR D
  64. G = J
  65. GOSUB shuffle
  66. FOR J = 16 TO 31
  67. F = ((B XOR C) AND D) XOR C
  68. G = (5 * J + 1) AND 15
  69. GOSUB shuffle
  70. FOR J = 32 TO 47
  71. F = B XOR C XOR D
  72. G = (3 * J + 5) AND 15
  73. GOSUB shuffle
  74. FOR J = 48 TO 63
  75. F = (D IMP B) XOR C
  76. G = (7 * J) AND 15
  77. GOSUB shuffle
  78.  
  79. h0 = add(h0, A)
  80. h1 = add(h1, B)
  81. h2 = add(h2, C)
  82. h3 = add(h3, D)
  83.  
  84.  
  85. MD5 = hexp(h0) + hexp(h1) + hexp(h2) + hexp(h3)
  86.  
  87. shuffle:
  88. temp = A
  89. A = D
  90. D = C
  91. C = B
  92. B = add(B, leftrotate(add(add(add(temp, F), Garbage(J)), mess(G)), r(J)))
  93.  
  94.