Find the MD4 message digest of a string of octets.
Use the ASCII encoded string “Rosetta Code” (without quotes).
You may either call an MD4 library, or implement MD4 in your language.

MD4 is an obsolete hash function that computes a 128-bit message digest that sometimes appears in obsolete protocols.

RFC 1320 specifies the MD4 algorithm. RFC 6150 declares that MD4 is obsolete.

' version 19-10-2016
' translation of the (pseudo) code in RFC 1320
' compile with: fbc -s console
 
Function MD4(test_str As String) As String
 
  Dim As String message = test_str ' string are passed as ByRef
 
  ' some macro's
  #Macro F(X, Y, Z)
    (((X) And (Y)) Or ((Not(X)) And (Z)))
  #EndMacro
 
  #Macro G(X, Y, Z)
    (((X) And (Y)) Or (((X) And (Z)) Or ((Y) And (Z))))
  #EndMacro
 
  #Macro H(X, Y, Z)
    ((X) Xor (Y) Xor (Z))
  #EndMacro
 
  ' a little piece of inline asm to do a rotate left on a 32bit variable
  #Macro ROtate_Left(x, n) ' rotate left
    Asm
      rol dword Ptr [x], n
    End Asm
  #EndMacro
 
  ' #Macro ROtate_left(x, n)
    ' x = x Shl n + x Shr (32 - n)
  ' #EndMacro
 
  Dim As Long i
  Dim As String answer, s1
 
  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
 
  ' unsigned 32bit integers only
  Dim As UInteger<32> AA, A = &H67452301
  Dim As UInteger<32> BB, B = &Hefcdab89
  Dim As UInteger<32> CC, C = &H98badcfe
  Dim As UInteger<32> DD, D = &H10325476
 
  For i = 0 To (l1 -1) \ 64 ' split into 64 byte block
 
    AA = A : BB = B : CC = C : DD = D
 
    ' x point to 64 byte block inside the string message
    Dim As UInteger<32> Ptr x = Cast(UInteger<32> Ptr, @message[i*64])
 
    ' round 1               
    A = A + F(B, C, D) + x[ 0] : ROtate_Left(A,  3)
    D = D + F(A, B, C) + x[ 1] : ROtate_Left(D,  7)
    C = C + F(D, A, B) + x[ 2] : ROtate_Left(C, 11)
    B = B + F(C, D, A) + x[ 3] : ROtate_Left(B, 19)
    A = A + F(B, C, D) + x[ 4] : ROtate_Left(A,  3)
    D = D + F(A, B, C) + x[ 5] : ROtate_Left(D,  7)
    C = C + F(D, A, B) + x[ 6] : ROtate_Left(C, 11)
    B = B + F(C, D, A) + x[ 7] : ROtate_Left(B, 19)
    A = A + F(B, C, D) + x[ 8] : ROtate_Left(A,  3)
    D = D + F(A, B, C) + x[ 9] : ROtate_Left(D,  7)
    C = C + F(D, A, B) + x[10] : ROtate_Left(C, 11)
    B = B + F(C, D, A) + x[11] : ROtate_Left(B, 19)
    A = A + F(B, C, D) + x[12] : ROtate_Left(A,  3)
    D = D + F(A, B, C) + x[13] : ROtate_Left(D,  7)
    C = C + F(D, A, B) + x[14] : ROtate_Left(C, 11)
    B = B + F(C, D, A) + x[15] : ROtate_Left(B, 19)
 
    ' round 2
    A = A + G(B, C, D) + x[ 0] + &H5A827999 : ROtate_Left(A,  3)
    D = D + G(A, B, C) + x[ 4] + &H5A827999 : ROtate_Left(D,  5)
    C = C + G(D, A, B) + x[ 8] + &H5A827999 : ROtate_Left(C,  9)
    B = B + G(C, D, A) + x[12] + &H5A827999 : ROtate_Left(B, 13)
    A = A + G(B, C, D) + x[ 1] + &H5A827999 : ROtate_Left(A,  3)
    D = D + G(A, B, C) + x[ 5] + &H5A827999 : ROtate_Left(D,  5)
    C = C + G(D, A, B) + x[ 9] + &H5A827999 : ROtate_Left(C,  9)
    B = B + G(C, D, A) + x[13] + &H5A827999 : ROtate_Left(B, 13)
    A = A + G(B, C, D) + x[ 2] + &H5A827999 : ROtate_Left(A,  3)
    D = D + G(A, B, C) + x[ 6] + &H5A827999 : ROtate_Left(D,  5)
    C = C + G(D, A, B) + x[10] + &H5A827999 : ROtate_Left(C,  9)
    B = B + G(C, D, A) + x[14] + &H5A827999 : ROtate_Left(B, 13)
    A = A + G(B, C, D) + x[ 3] + &H5A827999 : ROtate_Left(A,  3)
    D = D + G(A, B, C) + x[ 7] + &H5A827999 : ROtate_Left(D,  5)
    C = C + G(D, A, B) + x[11] + &H5A827999 : ROtate_Left(C,  9)
    B = B + G(C, D, A) + x[15] + &H5A827999 : ROtate_Left(B, 13)
 
    ' round 3
    A = A + H(B, C, D) + x[ 0] + &H6ED9EBA1 : ROtate_Left(A,  3)
    D = D + H(A, B, C) + x[ 8] + &H6ED9EBA1 : ROtate_Left(D,  9)
    C = C + H(D, A, B) + x[ 4] + &H6ED9EBA1 : ROtate_Left(C, 11)
    B = B + H(C, D, A) + x[12] + &H6ED9EBA1 : ROtate_Left(B, 15)
    A = A + H(B, C, D) + x[ 2] + &H6ED9EBA1 : ROtate_Left(A,  3)
    D = D + H(A, B, C) + x[10] + &H6ED9EBA1 : ROtate_Left(D,  9)
    C = C + H(D, A, B) + x[ 6] + &H6ED9EBA1 : ROtate_Left(C, 11)
    B = B + H(C, D, A) + x[14] + &H6ED9EBA1 : ROtate_Left(B, 15)
    A = A + H(B, C, D) + x[ 1] + &H6ED9EBA1 : ROtate_Left(A,  3)
    D = D + H(A, B, C) + x[ 9] + &H6ED9EBA1 : ROtate_Left(D,  9)
    C = C + H(D, A, B) + x[ 5] + &H6ED9EBA1 : ROtate_Left(C, 11)
    B = B + H(C, D, A) + x[13] + &H6ED9EBA1 : ROtate_Left(B, 15)
    A = A + H(B, C, D) + x[ 3] + &H6ED9EBA1 : ROtate_Left(A,  3)
    D = D + H(A, B, C) + x[11] + &H6ED9EBA1 : ROtate_Left(D,  9)
    C = C + H(D, A, B) + x[ 7] + &H6ED9EBA1 : ROtate_Left(C, 11)
    B = B + H(C, D, A) + x[15] + &H6ED9EBA1 : ROtate_Left(B, 15)
 
    A += AA : B += BB : C += CC : D += DD
 
  Next
 
  ' convert A, B, C and D in hex, then add low order first
  s1 = Hex(A, 8)
  For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
  s1 = Hex(B, 8)
  For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
  s1 = Hex(C, 8)
  For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
  s1 = Hex(D, 8)
  For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
 
Return LCase(answer)
 
End Function
 
' ------=< MAIN >=------
 
Dim As String test = "Rosetta Code"
Print
Print  test; " => "; MD4(test)
 
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End