' version 19-10-2016 ' MD5 from the Wikipedia page "MD5" ' compile with: fbc -s console ' macro for a rotate left #Macro ROtate_Left (x, n) ' rotate left (x) = (x) Shl (n) + (x) Shr (32 - (n)) #EndMacro Function MD5(test_str As String) As String Dim As String message = test_str ' strings are passed as ByRef's Dim As UByte sx, s(0 To ...) = { 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 } Dim As UInteger<32> K(0 To ...) = { &Hd76aa478, &He8c7b756, &H242070db, _ &Hc1bdceee, &Hf57c0faf, &H4787c62a, &Ha8304613, &Hfd469501, &H698098d8, _ &H8b44f7af, &Hffff5bb1, &H895cd7be, &H6b901122, &Hfd987193, &Ha679438e, _ &H49b40821, &Hf61e2562, &Hc040b340, &H265e5a51, &He9b6c7aa, &Hd62f105d, _ &H02441453, &Hd8a1e681, &He7d3fbc8, &H21e1cde6, &Hc33707d6, &Hf4d50d87, _ &H455a14ed, &Ha9e3e905, &Hfcefa3f8, &H676f02d9, &H8d2a4c8a, &Hfffa3942, _ &H8771f681, &H6d9d6122, &Hfde5380c, &Ha4beea44, &H4bdecfa9, &Hf6bb4b60, _ &Hbebfbc70, &H289b7ec6, &Heaa127fa, &Hd4ef3085, &H04881d05, &Hd9d4d039, _ &He6db99e5, &H1fa27cf8, &Hc4ac5665, &Hf4292244, &H432aff97, &Hab9423a7, _ &Hfc93a039, &H655b59c3, &H8f0ccc92, &Hffeff47d, &H85845dd1, &H6fa87e4f, _ &Hfe2ce6e0, &Ha3014314, &H4e0811a1, &Hf7537e82, &Hbd3af235, &H2ad7d2bb, _ &Heb86d391 } ' Initialize variables Dim As UInteger<32> A, a0 = &H67452301 Dim As UInteger<32> B, b0 = &Hefcdab89 Dim As UInteger<32> C, c0 = &H98badcfe Dim As UInteger<32> D, d0 = &H10325476 Dim As UInteger<32> dtemp, F, g, temp Dim As Long i, j Dim As ULongInt l = Len(message) ' set the first bit after the message to 1 message = message + Chr(1 Shl 7) ' add one char to the length Dim As ULong padding = 64 - ((l +1) Mod (512 \ 8)) ' 512 \ 8 = 64 char. ' check if we have enough room for inserting the length If padding < 8 Then padding = padding + 64 message = message + String(padding, Chr(0)) ' adjust length Dim As ULong l1 = Len(message) ' new length l = l * 8 ' orignal length in bits ' create ubyte ptr to point to l ( = length in bits) Dim As UByte Ptr ub_ptr = Cast(UByte Ptr, @l) For i = 0 To 7 'copy length of message to the last 8 bytes message[l1 -8 + i] = ub_ptr[i] Next For j = 0 To (l1 -1) \ 64 ' split into block of 64 bytes A = a0 : B = b0 : C = c0 : D = d0 ' break chunk into 16 32bit uinteger Dim As UInteger<32> Ptr M = Cast(UInteger<32> Ptr, @message[j * 64]) For i = 0 To 63 Select Case As Const i Case 0 To 15 F = (B And C) Or ((Not B) And D) g = i Case 16 To 31 F = (B And D) Or (C And (Not D)) g = (i * 5 +1) Mod 16 Case 32 To 47 F = (B Xor C Xor D) g = (i * 3 +5) Mod 16 Case 48 To 63 F = C Xor (B Or (Not D)) g = (i * 7) Mod 16 End Select dtemp = D D = C C = B temp = A + F + K(i)+ M[g] : ROtate_left(temp, s(i)) B = B + temp A = dtemp Next a0 += A : b0 += B : c0 += C : d0 += D Next Dim As String answer ' convert a0, b0, c0 and d0 in hex, then add, low order first Dim As String s1 = Hex(a0, 8) For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next s1 = Hex(b0, 8) For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next s1 = Hex(c0, 8) For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next s1 = Hex(d0, 8) For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next Return LCase(answer) End Function ' ------=< MAIN >=------ Dim As String test, hash, md5_hash Dim As ULong i For i = 1 To 7 Read hash, test md5_hash = MD5(test) Print Print test Print hash Print md5_hash; If hash = md5_hash Then Print " PASS" Else Print " FAIL" Beep End If Next ' testdata Data "d41d8cd98f00b204e9800998ecf8427e", "" Data "0cc175b9c0f1b6a831c399e269772661", "a" Data "900150983cd24fb0d6963f7d28e17f72", "abc" Data "f96b697d7cb7938d525a2f31aaf161d0", "message digest" Data "c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz" Data "d174ab98d277d9f5a5611c2c9f419d9f" Data "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" Data "57edf4a22be3c955ac49da2e2107b67a" Data "123456789012345678901234567890123456789012345678901234567890" _ + "12345678901234567890" ' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End