MD5/Implementation: Difference between revisions

Added BBC BASIC
m (warning box colour changed to soft yellow, red too harsh)
(Added BBC BASIC)
Line 325:
0x57edf4a22be3c955ac49da2e2107b67a
0x57edf4a22be3c955ac49da2e2107b67a (correct value)</pre>
 
=={{header|BBC BASIC}}==
<lang bbcbasic> PRINT FN_MD5("")
PRINT FN_MD5("a")
PRINT FN_MD5("abc")
PRINT FN_MD5("message digest")
PRINT FN_MD5("abcdefghijklmnopqrstuvwxyz")
PRINT FN_MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
PRINT FN_MD5(STRING$(8,"1234567890"))
END
DEF FN_MD5(message$)
LOCAL a%, b%, c%, d%, f%, g%, h0%, h1%, h2%, h3%, i%, bits%, chunk%, temp%
LOCAL r&(), k%(), w%()
DIM r&(63), k%(63), w%(15)
REM r specifies the per-round shift amounts:
r&() = 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, \
\ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, \
\ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, \
\ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
REM Use binary integer part of the sines of integers (Radians) as constants:
FOR i% = 0 TO 63
k%(i%) = FN32(INT(ABS(SIN(i% + 1.0#)) * 2^32))
NEXT
REM Initialize variables:
h0% = &67452301
h1% = &EFCDAB89
h2% = &98BADCFE
h3% = &10325476
bits% = LEN(message$)*8
REM Append '1' bit to message:
message$ += CHR$&80
REM Append '0' bits until message length in bits = 448 (mod 512):
WHILE (LEN(message$) MOD 64) <> 56
message$ += CHR$0
ENDWHILE
REM Append length of message (before pre-processing), in bits, as
REM 64-bit little-endian integer:
FOR i% = 0 TO 56 STEP 8
message$ += CHR$(bits% >>> i%)
NEXT
REM Process the message in successive 512-bit chunks:
FOR chunk% = 0 TO LEN(message$) DIV 64 - 1
REM Break chunk into sixteen 32-bit little-endian words:
FOR i% = 0 TO 15
w%(i%) = !(!^message$ + 64*chunk% + 4*i%)
NEXT i%
REM Initialize hash value for this chunk:
a% = h0%
b% = h1%
c% = h2%
d% = h3%
REM Main loop:
FOR i% = 0 TO 63
CASE TRUE OF
WHEN i% <= 15:
f% = d% EOR (b% AND (c% EOR d%))
g% = i%
WHEN 16 <= i% AND i% <= 31:
f% = c% EOR (d% AND (b% EOR c%))
g% = (5 * i% + 1) MOD 16
WHEN 32 <= i% AND i% <= 47:
f% = b% EOR c% EOR d%
g% = (3 * i% + 5) MOD 16
OTHERWISE:
f% = c% EOR (b% OR (NOT d%))
g% = (7 * i%) MOD 16
ENDCASE
temp% = d%
d% = c%
c% = b%
b% = FN32(b% + FNlrot(FN32(a% + f%) + FN32(k%(i%) + w%(g%)), r&(i%)))
a% = temp%
NEXT i%
REM Add this chunk's hash to result so far:
h0% = FN32(h0% + a%)
h1% = FN32(h1% + b%)
h2% = FN32(h2% + c%)
h3% = FN32(h3% + d%)
NEXT chunk%
= FNrevhex(h0%) + FNrevhex(h1%) + FNrevhex(h2%) + FNrevhex(h3%)
DEF FNrevhex(A%)
SWAP ?(^A%+0),?(^A%+3)
SWAP ?(^A%+1),?(^A%+2)
= RIGHT$("0000000"+STR$~A%,8)
DEF FNlrot(n#, r%)
n# = FN32(n#)
= (n# << r%) OR (n# >>> (32 - r%))
DEF FN32(n#)
WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE
WHILE n# < &80000000 : n# += 2^32 : ENDWHILE
= n#</lang>
 
=={{header|C sharp}}==