MD4: Difference between revisions

From Rosetta Code
Content added Content deleted
(Ada version)
Line 8: Line 8:


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

=={{header|Ada}}==
{{libheader|CryptAda}}
<lang Ada>with CryptAda.Digests.Message_Digests.MD4;
with CryptAda.Digests.Hashes;
with CryptAda.Pragmatics;
with CryptAda.Utils.Format;

procedure RC_MD4 is
use CryptAda.Digests.Message_Digests;
use CryptAda.Digests;
use CryptAda.Pragmatics;

function To_Byte_Array (Item : String) return Byte_Array is
Result : Byte_Array (Item'Range);
begin
for I in Result'Range loop
Result (I) := Byte (Character'Pos (Item (I)));
end loop;
return Result;
end To_Byte_Array;

Text : constant String := "Rosetta Code";
Bytes : constant Byte_Array := To_Byte_Array (Text);
Handle : constant Message_Digest_Handle := MD4.Get_Message_Digest_Handle;
Pointer : constant Message_Digest_Ptr := Get_Message_Digest_Ptr (Handle);
Hash : Hashes.Hash;
begin
Digest_Start (Pointer);
Digest_Update (Pointer, Bytes);
Digest_End (Pointer, Hash);

Ada.Text_IO.Put_Line
("""" & Text & """: " & CryptAda.Utils.Format.To_Hex_String (Hashes.Get_Bytes (Hash)));
end RC_MD4;</lang>
{{out}}
<pre>"Rosetta Code": A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==

Revision as of 21:07, 28 December 2019

Task
MD4
You are encouraged to solve this task according to the task description, using any language you may know.

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.

Ada

Library: CryptAda

<lang Ada>with CryptAda.Digests.Message_Digests.MD4; with CryptAda.Digests.Hashes; with CryptAda.Pragmatics; with CryptAda.Utils.Format;

procedure RC_MD4 is

  use CryptAda.Digests.Message_Digests;
  use CryptAda.Digests;
  use CryptAda.Pragmatics;
  function To_Byte_Array (Item : String) return Byte_Array is
     Result : Byte_Array (Item'Range);
  begin
     for I in Result'Range loop
        Result (I) := Byte (Character'Pos (Item (I)));
     end loop;
     return Result;
  end To_Byte_Array;
  Text    : constant String                := "Rosetta Code";
  Bytes   : constant Byte_Array            := To_Byte_Array (Text);
  Handle  : constant Message_Digest_Handle := MD4.Get_Message_Digest_Handle;
  Pointer : constant Message_Digest_Ptr    := Get_Message_Digest_Ptr (Handle);
  Hash    : Hashes.Hash;

begin

  Digest_Start  (Pointer);
  Digest_Update (Pointer, Bytes);
  Digest_End    (Pointer, Hash);
  Ada.Text_IO.Put_Line
    ("""" & Text & """: " & CryptAda.Utils.Format.To_Hex_String (Hashes.Get_Bytes (Hash)));

end RC_MD4;</lang>

Output:
"Rosetta Code": A52BCFC6A0D0D300CDC5DDBFBEFE478B

AutoHotkey

Source: MD4 @github by jNizM <lang AutoHotkey>str := "Rosetta Code" MsgBox, % "String:`n" (str) "`n`nMD4:`n" MD4(str)


MD4 ===============================================================================

MD4(string, encoding = "utf-8") {

   return CalcStringHash(string, 0x8002, encoding)

}

CalcAddrHash ======================================================================

CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0) {

   static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"]
   static b := h.minIndex()
   o := ""
   if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xF0000000))
   {
       if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash))
       {
           if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0))
           {
               if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0))
               {
                   VarSetCapacity(hash, hashlength, 0)
                   if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0))
                   {
                       loop, % hashlength
                       {
                           v := NumGet(hash, A_Index - 1, "UChar")
                           o .= h[(v >> 4) + b] h[(v & 0xf) + b]
                       }
                   }
               }
           }
           DllCall("advapi32\CryptDestroyHash", "Ptr", hHash)
       }
       DllCall("advapi32\CryPtreleaseContext", "Ptr", hProv, "UInt", 0)
   }
   return o

}

CalcStringHash ====================================================================

CalcStringHash(string, algid, encoding = "utf-8", byref hash = 0, byref hashlength = 0) {

   chrlength := (encoding = "cp1200" || encoding = "utf-16") ? 2 : 1
   length := (StrPut(string, encoding) - 1) * chrlength
   VarSetCapacity(data, length, 0)
   StrPut(string, &data, floor(length / chrlength), encoding)
   return CalcAddrHash(&data, length, algid, hash, hashlength)

}</lang>

Output:
String:    Rosetta Code
MD4:       A52BCFC6A0D0D300CDC5DDBFBEFE478B

C

<lang C> /*

*
*      Author: George Mossessian
*
*      The MD4 hash algorithm, as described in https://tools.ietf.org/html/rfc1320
*/


  1. include <stdlib.h>
  2. include <string.h>
  3. include <stdint.h>

char *MD4(char *str, int len); //this is the prototype you want to call. Everything else is internal.

typedef struct string{

       char *c;
       int len;
       char sign;

}string;

static uint32_t *MD4Digest(uint32_t *w, int len); static void setMD4Registers(uint32_t AA, uint32_t BB, uint32_t CC, uint32_t DD); static uint32_t changeEndianness(uint32_t x); static void resetMD4Registers(void); static string stringCat(string first, string second); static string uint32ToString(uint32_t l); static uint32_t stringToUint32(string s);

static const char *BASE16 = "0123456789abcdef=";

  1. define F(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
  2. define G(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
  3. define H(X,Y,Z) ((X)^(Y)^(Z))
  1. define LEFTROTATE(A,N) ((A)<<(N))|((A)>>(32-(N)))
  1. define MD4ROUND1(a,b,c,d,x,s) a += F(b,c,d) + x; a = LEFTROTATE(a, s);
  2. define MD4ROUND2(a,b,c,d,x,s) a += G(b,c,d) + x + (uint32_t)0x5A827999; a = LEFTROTATE(a, s);
  3. define MD4ROUND3(a,b,c,d,x,s) a += H(b,c,d) + x + (uint32_t)0x6ED9EBA1; a = LEFTROTATE(a, s);

static uint32_t A = 0x67452301; static uint32_t B = 0xefcdab89; static uint32_t C = 0x98badcfe; static uint32_t D = 0x10325476;

string newString(char * c, int t){ string r; int i; if(c!=NULL){ r.len = (t<=0)?strlen(c):t; r.c=(char *)malloc(sizeof(char)*(r.len+1)); for(i=0; i<r.len; i++) r.c[i]=c[i]; r.c[r.len]='\0'; return r; } r.len=t; r.c=(char *)malloc(sizeof(char)*(r.len+1)); memset(r.c,(char)0,sizeof(char)*(t+1)); r.sign = 1; return r; }

string stringCat(string first, string second){ string str=newString(NULL, first.len+second.len); int i;

for(i=0; i<first.len; i++){ str.c[i]=first.c[i]; } for(i=first.len; i<str.len; i++){ str.c[i]=second.c[i-first.len]; } return str; }

string base16Encode(string in){ string out=newString(NULL, in.len*2); int i,j;

j=0; for(i=0; i<in.len; i++){ out.c[j++]=BASE16[((in.c[i] & 0xF0)>>4)]; out.c[j++]=BASE16[(in.c[i] & 0x0F)]; } out.c[j]='\0'; return out; }


string uint32ToString(uint32_t l){ string s = newString(NULL,4); int i; for(i=0; i<4; i++){ s.c[i] = (l >> (8*(3-i))) & 0xFF; } return s; }

uint32_t stringToUint32(string s){ uint32_t l; int i; l=0; for(i=0; i<4; i++){ l = l|(((uint32_t)((unsigned char)s.c[i]))<<(8*(3-i))); } return l; }

char *MD4(char *str, int len){ string m=newString(str, len); string digest; uint32_t *w; uint32_t *hash; uint64_t mlen=m.len; unsigned char oneBit = 0x80; int i, wlen;


m=stringCat(m, newString((char *)&oneBit,1));

//append 0 ≤ k < 512 bits '0', such that the resulting message length in bits // is congruent to −64 ≡ 448 (mod 512)4 i=((56-m.len)%64); if(i<0) i+=64; m=stringCat(m,newString(NULL, i));

w = malloc(sizeof(uint32_t)*(m.len/4+2));

//append length, in bits (hence <<3), least significant word first for(i=0; i<m.len/4; i++){ w[i]=stringToUint32(newString(&(m.c[4*i]), 4)); } w[i++] = (mlen<<3) & 0xFFFFFFFF; w[i++] = (mlen>>29) & 0xFFFFFFFF;

wlen=i;


//change endianness, but not for the appended message length, for some reason? for(i=0; i<wlen-2; i++){ w[i]=changeEndianness(w[i]); }

hash = MD4Digest(w,wlen);

digest=newString(NULL,0); for(i=0; i<4; i++){ hash[i]=changeEndianness(hash[i]); digest=stringCat(digest,uint32ToString(hash[i])); }

return base16Encode(digest).c; }

uint32_t *MD4Digest(uint32_t *w, int len){ //assumes message.len is a multiple of 64 bytes. int i,j; uint32_t X[16]; uint32_t *digest = malloc(sizeof(uint32_t)*4); uint32_t AA, BB, CC, DD;

for(i=0; i<len/16; i++){ for(j=0; j<16; j++){ X[j]=w[i*16+j]; }

AA=A; BB=B; CC=C; DD=D;

MD4ROUND1(A,B,C,D,X[0],3); MD4ROUND1(D,A,B,C,X[1],7); MD4ROUND1(C,D,A,B,X[2],11); MD4ROUND1(B,C,D,A,X[3],19); MD4ROUND1(A,B,C,D,X[4],3); MD4ROUND1(D,A,B,C,X[5],7); MD4ROUND1(C,D,A,B,X[6],11); MD4ROUND1(B,C,D,A,X[7],19); MD4ROUND1(A,B,C,D,X[8],3); MD4ROUND1(D,A,B,C,X[9],7); MD4ROUND1(C,D,A,B,X[10],11); MD4ROUND1(B,C,D,A,X[11],19); MD4ROUND1(A,B,C,D,X[12],3); MD4ROUND1(D,A,B,C,X[13],7); MD4ROUND1(C,D,A,B,X[14],11); MD4ROUND1(B,C,D,A,X[15],19);

MD4ROUND2(A,B,C,D,X[0],3); MD4ROUND2(D,A,B,C,X[4],5); MD4ROUND2(C,D,A,B,X[8],9); MD4ROUND2(B,C,D,A,X[12],13); MD4ROUND2(A,B,C,D,X[1],3); MD4ROUND2(D,A,B,C,X[5],5); MD4ROUND2(C,D,A,B,X[9],9); MD4ROUND2(B,C,D,A,X[13],13); MD4ROUND2(A,B,C,D,X[2],3); MD4ROUND2(D,A,B,C,X[6],5); MD4ROUND2(C,D,A,B,X[10],9); MD4ROUND2(B,C,D,A,X[14],13); MD4ROUND2(A,B,C,D,X[3],3); MD4ROUND2(D,A,B,C,X[7],5); MD4ROUND2(C,D,A,B,X[11],9); MD4ROUND2(B,C,D,A,X[15],13);

MD4ROUND3(A,B,C,D,X[0],3); MD4ROUND3(D,A,B,C,X[8],9); MD4ROUND3(C,D,A,B,X[4],11); MD4ROUND3(B,C,D,A,X[12],15); MD4ROUND3(A,B,C,D,X[2],3); MD4ROUND3(D,A,B,C,X[10],9); MD4ROUND3(C,D,A,B,X[6],11); MD4ROUND3(B,C,D,A,X[14],15); MD4ROUND3(A,B,C,D,X[1],3); MD4ROUND3(D,A,B,C,X[9],9); MD4ROUND3(C,D,A,B,X[5],11); MD4ROUND3(B,C,D,A,X[13],15); MD4ROUND3(A,B,C,D,X[3],3); MD4ROUND3(D,A,B,C,X[11],9); MD4ROUND3(C,D,A,B,X[7],11); MD4ROUND3(B,C,D,A,X[15],15);

A+=AA; B+=BB; C+=CC; D+=DD; }

digest[0]=A; digest[1]=B; digest[2]=C; digest[3]=D; resetMD4Registers(); return digest; }

uint32_t changeEndianness(uint32_t x){ return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); }

void setMD4Registers(uint32_t AA, uint32_t BB, uint32_t CC, uint32_t DD){ A=AA; B=BB; C=CC; D=DD; }

void resetMD4Registers(void){ setMD4Registers(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476); } </lang>

Output:

<lang C>printf("%s\n", MD4("Rosetta Code", 12));</lang>

a52bcfc6a0d0d300cdc5ddbfbefe478b


C#

<lang csharp>using System; using System.Collections.Generic; using System.Linq; using System.Text; static class Md4 {

   public static string Md4Hash(this string input)
   {
       // get padded uints from bytes
       List<byte> bytes = Encoding.ASCII.GetBytes(input).ToList();
       uint bitCount = (uint)(bytes.Count) * 8;
       bytes.Add(128);
       while (bytes.Count % 64 != 56) bytes.Add(0);
       var uints = new List<uint>();
       for (int i = 0; i + 3 < bytes.Count; i += 4)
           uints.Add(bytes[i] | (uint)bytes[i + 1] << 8 | (uint)bytes[i + 2] << 16 | (uint)bytes[i + 3] << 24);
       uints.Add(bitCount);
       uints.Add(0);
       // run rounds
       uint a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476;
       Func<uint, uint, uint> rol = (x, y) => x << (int)y | x >> 32 - (int)y;
       for (int q = 0; q + 15 < uints.Count; q += 16)
       {
           var chunk = uints.GetRange(q, 16);
           uint aa = a, bb = b, cc = c, dd = d;
           Action<Func<uint, uint, uint, uint>, uint[]> round = (f, y) =>
           {
               foreach (uint i in new[] { y[0], y[1], y[2], y[3] })
               {
                   a = rol(a + f(b, c, d) + chunk[(int)(i + y[4])] + y[12], y[8]);
                   d = rol(d + f(a, b, c) + chunk[(int)(i + y[5])] + y[12], y[9]);
                   c = rol(c + f(d, a, b) + chunk[(int)(i + y[6])] + y[12], y[10]);
                   b = rol(b + f(c, d, a) + chunk[(int)(i + y[7])] + y[12], y[11]);
               }
           };
           round((x, y, z) => (x & y) | (~x & z), new uint[] { 0, 4, 8, 12, 0, 1, 2, 3, 3, 7, 11, 19, 0 });
           round((x, y, z) => (x & y) | (x & z) | (y & z), new uint[] { 0, 1, 2, 3, 0, 4, 8, 12, 3, 5, 9, 13, 0x5a827999 });
           round((x, y, z) => x ^ y ^ z, new uint[] { 0, 2, 1, 3, 0, 8, 4, 12, 3, 9, 11, 15, 0x6ed9eba1 });
           a += aa; b += bb; c += cc; d += dd;
       }
       // return hex encoded string
       byte[] outBytes = new[] { a, b, c, d }.SelectMany(BitConverter.GetBytes).ToArray();
       return BitConverter.ToString(outBytes).Replace("-", "").ToLower();
   }
   static void Main() { Console.WriteLine("Rosetta Code".Md4Hash()); }

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Clojure

Library: pandect

<lang clojure>(use 'pandect.core) (md4 "Rosetta Code")</lang>

Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"

Common Lisp

Library: Ironclad

<lang lisp>(ql:quickload 'ironclad) (defun md4 (str)

 (ironclad:byte-array-to-hex-string
   (ironclad:digest-sequence :md4 
                             (ironclad:ascii-string-to-byte-array str))))

(md4 "Rosetta Code")</lang>

Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"

D

A short but not efficient implementation.

Translation of: Ruby

<lang d>import std.stdio, std.string, std.range;

ubyte[16] md4(const(ubyte)[] inData) pure nothrow {

   enum f = (uint x, uint y, uint z) => (x & y) | (~x & z);
   enum g = (uint x, uint y, uint z) => (x & y) | (x & z) | (y & z);
   enum h = (uint x, uint y, uint z) => x ^ y ^ z;
   enum r = (uint v, uint s) => (v << s) | (v >> (32 - s));
   immutable bitLen = ulong(inData.length) << 3;
   inData ~= 0x80;
   while (inData.length % 64 != 56)
       inData ~= 0;
   const data = cast(uint[])inData ~ [uint(bitLen & uint.max), uint(bitLen >> 32)];
   uint a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476;
   foreach (const x; data.chunks(16)) {
       immutable a2 = a, b2 = b, c2 = c, d2 = d;
       foreach (immutable i; [0, 4, 8, 12]) {
           a = r(a + f(b, c, d) + x[i+0],  3);
           d = r(d + f(a, b, c) + x[i+1],  7);
           c = r(c + f(d, a, b) + x[i+2], 11);
           b = r(b + f(c, d, a) + x[i+3], 19);
       }
       foreach (immutable i; [0, 1, 2, 3]) {
           a = r(a + g(b, c, d) + x[i+0] + 0x5a827999,  3);
           d = r(d + g(a, b, c) + x[i+4] + 0x5a827999,  5);
           c = r(c + g(d, a, b) + x[i+8] + 0x5a827999,  9);
           b = r(b + g(c, d, a) + x[i+12] + 0x5a827999, 13);
       }
       foreach (immutable i; [0, 2, 1, 3]) {
           a = r(a + h(b, c, d) + x[i+0] + 0x6ed9eba1,  3);
           d = r(d + h(a, b, c) + x[i+8] + 0x6ed9eba1,  9);
           c = r(c + h(d, a, b) + x[i+4] + 0x6ed9eba1, 11);
           b = r(b + h(c, d, a) + x[i+12] + 0x6ed9eba1, 15);
       }
       a += a2, b += b2, c += c2, d += d2;
   }
   //return cast(ubyte[16])[a, b, c, d];
   immutable uint[4] result = [a, b, c, d];
   return cast(ubyte[16])result;

}

void main() {

   writefln("%(%02x%)", "Rosetta Code".representation.md4);

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Emacs Lisp

md4.el by Taro Kawagishi, originally from FLIM and included in recent Emacs, is an Elisp implementation of the MD4 algorithm. Its md4 function returns the checksum as 16 binary bytes. encode-hex-string from hex-util.el can convert that to a hex string if desired.

<lang Lisp>(require 'md4) (let* ((s "Rosetta Code")

      (m  (md4 s (length s)))) ;; m = 16 binary bytes
 (require 'hex-util)
 (encode-hex-string m))

=> "a52bcfc6a0d0d300cdc5ddbfbefe478b"</lang>

Erlang

<lang erlang> -module(md4). -export([md4/0]).

md4() ->

   <<MD4:128>> = crypto:md4("Rosetta Code"),
   io:fwrite("Rosetta Code => ~.16B~n",[MD4]).

</lang>

Rosetta Code => A52BCFC6A0D0D300CDC5DDBFBEFE478B

FreeBASIC

<lang freebasic>' 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</lang>

Output:
Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b

Haskell

Library: Cryptonite

<lang haskell>#!/usr/bin/env runhaskell

import Data.ByteString.Char8 (pack) import System.Environment (getArgs) import Crypto.Hash

main :: IO () main = print . md4 . pack . unwords =<< getArgs

        where md4 x = hash x :: Digest MD4</lang>
Output:
$ ./md4.hs Rosetta Code
a52bcfc6a0d0d300cdc5ddbfbefe478b

Go

<lang go>package main

import (

   "golang.org/x/crypto/md4"
   "fmt"

)

func main() {

   h := md4.New()
   h.Write([]byte("Rosetta Code"))
   fmt.Printf("%x\n", h.Sum(nil))

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

J

<lang j> require 'ide/qt'

  gethash_jqtide_ 'MD4';'Rosetta Code'

a52bcfc6a0d0d300cdc5ddbfbefe478b</lang>

Java

Library: BouncyCastle

<lang java>import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.util.encoders.Hex;

public class RosettaMD4 {

   public static void main (String[] argv) throws Exception
   {
       byte[] r = "Rosetta Code".getBytes("US-ASCII");
       MD4Digest d = new MD4Digest();
       d.update (r, 0, r.length);
       byte[] o = new byte[d.getDigestSize()];
       d.doFinal (o, 0);
       Hex.encode (o, System.out);
       System.out.println();
   }

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

JavaScript

<lang javascript>const md4func = () => {

 const hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase    */
 const b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance  */
 const chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode   */
 const tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 const hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
 /**
  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
  * to work around bugs in some JS interpreters.
  */
 const safe_add = (x, y) => {
   const lsw = (x & 0xFFFF) + (y & 0xFFFF);
   const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
   return (msw << 16) | (lsw & 0xFFFF);
 };
 /**
  * Bitwise rotate a 32-bit number to the left.
  */
 const rol = (num, cnt) => (num << cnt) | (num >>> (32 - cnt));
 /**
  * Convert a string to an array of little-endian words
  * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
  */
 const str2binl = str => {
   const bin = Array();
   const mask = (1 << chrsz) - 1;
   for (let i = 0; i < str.length * chrsz; i += chrsz)
     bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
   return bin;
 };
 /**
  * Convert an array of little-endian words to a string
  */
 const binl2str = bin => {
   let str = "";
   const mask = (1 << chrsz) - 1;
   for (let i = 0; i < bin.length * 32; i += chrsz)
     str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
   return str;
 };
 /**
  * Convert an array of little-endian words to a hex string.
  */
 const binl2hex = binarray => {
   let str = "";
   for (let i = 0; i < binarray.length * 4; i++) {
     str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
         hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
   }
   return str;
 };
 /**
  * Convert an array of little-endian words to a base-64 string
  */
 const binl2b64 = binarray => {
   let str = "";
   for (let i = 0; i < binarray.length * 4; i += 3) {
     const triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
         | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
         | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
     for (let j = 0; j < 4; j++) {
       if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
       else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
     }
   }
   return str;
 };


 /**
  * Calculate the MD4 of an array of little-endian words, and a bit length
  */
 const core_md4 = (x, len) => {
   x[len >> 5] |= 0x80 << (len % 32);
   x[(((len + 64) >>> 9) << 4) + 14] = len;
   let a = 1732584193;
   let b = -271733879;
   let c = -1732584194;
   let d = 271733878;
   for (let i = 0; i < x.length; i += 16) {
     const olda = a;
     const oldb = b;
     const oldc = c;
     const oldd = d;
     a = md4_ff(a, b, c, d, x[i], 3);
     d = md4_ff(d, a, b, c, x[i + 1], 7);
     c = md4_ff(c, d, a, b, x[i + 2], 11);
     b = md4_ff(b, c, d, a, x[i + 3], 19);
     a = md4_ff(a, b, c, d, x[i + 4], 3);
     d = md4_ff(d, a, b, c, x[i + 5], 7);
     c = md4_ff(c, d, a, b, x[i + 6], 11);
     b = md4_ff(b, c, d, a, x[i + 7], 19);
     a = md4_ff(a, b, c, d, x[i + 8], 3);
     d = md4_ff(d, a, b, c, x[i + 9], 7);
     c = md4_ff(c, d, a, b, x[i + 10], 11);
     b = md4_ff(b, c, d, a, x[i + 11], 19);
     a = md4_ff(a, b, c, d, x[i + 12], 3);
     d = md4_ff(d, a, b, c, x[i + 13], 7);
     c = md4_ff(c, d, a, b, x[i + 14], 11);
     b = md4_ff(b, c, d, a, x[i + 15], 19);
     a = md4_gg(a, b, c, d, x[i], 3);
     d = md4_gg(d, a, b, c, x[i + 4], 5);
     c = md4_gg(c, d, a, b, x[i + 8], 9);
     b = md4_gg(b, c, d, a, x[i + 12], 13);
     a = md4_gg(a, b, c, d, x[i + 1], 3);
     d = md4_gg(d, a, b, c, x[i + 5], 5);
     c = md4_gg(c, d, a, b, x[i + 9], 9);
     b = md4_gg(b, c, d, a, x[i + 13], 13);
     a = md4_gg(a, b, c, d, x[i + 2], 3);
     d = md4_gg(d, a, b, c, x[i + 6], 5);
     c = md4_gg(c, d, a, b, x[i + 10], 9);
     b = md4_gg(b, c, d, a, x[i + 14], 13);
     a = md4_gg(a, b, c, d, x[i + 3], 3);
     d = md4_gg(d, a, b, c, x[i + 7], 5);
     c = md4_gg(c, d, a, b, x[i + 11], 9);
     b = md4_gg(b, c, d, a, x[i + 15], 13);
     a = md4_hh(a, b, c, d, x[i], 3);
     d = md4_hh(d, a, b, c, x[i + 8], 9);
     c = md4_hh(c, d, a, b, x[i + 4], 11);
     b = md4_hh(b, c, d, a, x[i + 12], 15);
     a = md4_hh(a, b, c, d, x[i + 2], 3);
     d = md4_hh(d, a, b, c, x[i + 10], 9);
     c = md4_hh(c, d, a, b, x[i + 6], 11);
     b = md4_hh(b, c, d, a, x[i + 14], 15);
     a = md4_hh(a, b, c, d, x[i + 1], 3);
     d = md4_hh(d, a, b, c, x[i + 9], 9);
     c = md4_hh(c, d, a, b, x[i + 5], 11);
     b = md4_hh(b, c, d, a, x[i + 13], 15);
     a = md4_hh(a, b, c, d, x[i + 3], 3);
     d = md4_hh(d, a, b, c, x[i + 11], 9);
     c = md4_hh(c, d, a, b, x[i + 7], 11);
     b = md4_hh(b, c, d, a, x[i + 15], 15);
     a = safe_add(a, olda);
     b = safe_add(b, oldb);
     c = safe_add(c, oldc);
     d = safe_add(d, oldd);
   }
   return Array(a, b, c, d);
 };
 /**
  * These functions implement the basic operation for each round of the
  * algorithm.
  */
 const md4_cmn = (q, a, b, x, s, t) => safe_add(
     rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
 const md4_ff = (a, b, c, d, x, s) => md4_cmn(
     (b & c) | ((~b) & d), a, 0, x, s, 0);
 const md4_gg = (a, b, c, d, x, s) => md4_cmn(
     (b & c) | (b & d) | (c & d), a, 0, x, s, 1518500249);
 const md4_hh = (a, b, c, d, x, s) => md4_cmn(
     b ^ c ^ d, a, 0, x, s, 1859775393);
 /**
  * Calculate the HMAC-MD4, of a key and some data
  */
 const core_hmac_md4 = (key, data) => {
   let bkey = str2binl(key);
   if (bkey.length > 16) {
     bkey = core_md4(bkey, key.length * chrsz)
   }
   const ipad = Array(16);
   const opad = Array(16);
   for (let i = 0; i < 16; i++) {
     ipad[i] = bkey[i] ^ 0x36363636;
     opad[i] = bkey[i] ^ 0x5C5C5C5C;
   }
   const hash = core_md4(
       ipad.concat(str2binl(data)), 512 + data.length * chrsz);
   return core_md4(opad.concat(hash), 512 + 128);
 };
 /**
  * These are the functions you'll usually want to call
  */
 return {
   hex_md4: s => binl2hex(core_md4(str2binl(s), s.length * chrsz)),
   b64_md4: s => binl2b64(core_md4(str2binl(s), s.length * chrsz)),
   str_md4: s => binl2str(core_md4(str2binl(s), s.length * chrsz)),
   hex_hmac_md4: (key, data) => binl2hex(core_hmac_md4(key, data)),
   b64_hmac_md4: (key, data) => binl2b64(core_hmac_md4(key, data)),
   str_hmac_md4: (key, data) => binl2str(core_hmac_md4(key, data)),
 };

};

const md4 = md4func(); console.log(md4.hex_md4('Rosetta Code'));</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Julia

Nettle.jl provides a variety of cryptographic functions including the MD4 hash. <lang Julia> using Nettle

msg = "Rosetta Code"

h = HashState(MD4) update!(h, msg) h = hexdigest!(h)

println("\"", msg, "\" => ", h) </lang>

Output:
"Rosetta Code" => a52bcfc6a0d0d300cdc5ddbfbefe478b

Kotlin

This is a translation of the Java code here. In the interests of conciseness, I have removed the comments from the Kotlin version: <lang scala>// version 1.0.6

import java.security.MessageDigest

class MD4() : MessageDigest("MD4"), Cloneable {

   private val blockLength = 64
   private var context = IntArray(4)
   private var count = 0L
   private var buffer = ByteArray(blockLength)
   private var x = IntArray(16)
 
   init {
       engineReset()
   }
   private constructor(md: MD4): this() {
       context = md.context.clone()
       buffer = md.buffer.clone()
       count = md.count
   } 
   override fun clone(): Any = MD4(this)
   override fun engineReset() {
       context[0] = 0x67452301
       context[1] = 0xefcdab89.toInt() 
       context[2] = 0x98badcfe.toInt()
       context[3] = 0x10325476
       count = 0L
       for (i in 0 until blockLength) buffer[i] = 0
   }
   override fun engineUpdate(b: Byte) {
       val i = (count % blockLength).toInt()
       count++                                 
       buffer[i] = b
       if (i == blockLength - 1) transform(buffer, 0)
   }
   override fun engineUpdate(input: ByteArray, offset: Int, len: Int) {
       if (offset < 0 || len < 0 || offset.toLong() + len > input.size.toLong())
           throw ArrayIndexOutOfBoundsException()
       var bufferNdx = (count % blockLength).toInt()
       count += len                                    
       val partLen = blockLength - bufferNdx
       var i = 0
       if (len >= partLen) {
           System.arraycopy(input, offset, buffer, bufferNdx, partLen)
           transform(buffer, 0)
           i = partLen
           while (i + blockLength - 1 < len) {
               transform(input, offset + i)
               i += blockLength
           }
           bufferNdx = 0
       }
       if (i < len) System.arraycopy(input, offset + i, buffer, bufferNdx, len - i)
   }
   override fun engineDigest(): ByteArray {
       val bufferNdx = (count % blockLength).toInt()
       val padLen = if (bufferNdx < 56) 56 - bufferNdx else 120 - bufferNdx
       val tail = ByteArray(padLen + 8)
       tail[0] = 0x80.toByte()
       for (i in 0..7) tail[padLen + i] = ((count * 8) ushr (8 * i)).toByte()
       engineUpdate(tail, 0, tail.size)
       val result = ByteArray(16)
       for (i in 0..3)
           for (j in 0..3)
               result[i * 4 + j] = (context[i] ushr (8 * j)).toByte()
       engineReset()
       return result
   }
   private fun transform (block: ByteArray, offset: Int) {
       var offset2 = offset
       for (i in 0..15) 
           x[i] = ((block[offset2++].toInt() and 0xff)       ) or
                  ((block[offset2++].toInt() and 0xff) shl 8 ) or
                  ((block[offset2++].toInt() and 0xff) shl 16) or
                  ((block[offset2++].toInt() and 0xff) shl 24)
       var a = context[0]
       var b = context[1]
       var c = context[2]
       var d = context[3]
       a = ff(a, b, c, d, x[ 0],  3)
       d = ff(d, a, b, c, x[ 1],  7)
       c = ff(c, d, a, b, x[ 2], 11)
       b = ff(b, c, d, a, x[ 3], 19)
       a = ff(a, b, c, d, x[ 4],  3)
       d = ff(d, a, b, c, x[ 5],  7)
       c = ff(c, d, a, b, x[ 6], 11)
       b = ff(b, c, d, a, x[ 7], 19)
       a = ff(a, b, c, d, x[ 8],  3)
       d = ff(d, a, b, c, x[ 9],  7)
       c = ff(c, d, a, b, x[10], 11)
       b = ff(b, c, d, a, x[11], 19)
       a = ff(a, b, c, d, x[12],  3)
       d = ff(d, a, b, c, x[13],  7)
       c = ff(c, d, a, b, x[14], 11)
       b = ff(b, c, d, a, x[15], 19)
       a = gg(a, b, c, d, x[ 0],  3)
       d = gg(d, a, b, c, x[ 4],  5)
       c = gg(c, d, a, b, x[ 8],  9)
       b = gg(b, c, d, a, x[12], 13)
       a = gg(a, b, c, d, x[ 1],  3)
       d = gg(d, a, b, c, x[ 5],  5)
       c = gg(c, d, a, b, x[ 9],  9)
       b = gg(b, c, d, a, x[13], 13)
       a = gg(a, b, c, d, x[ 2],  3)
       d = gg(d, a, b, c, x[ 6],  5)
       c = gg(c, d, a, b, x[10],  9)
       b = gg(b, c, d, a, x[14], 13)
       a = gg(a, b, c, d, x[ 3],  3)
       d = gg(d, a, b, c, x[ 7],  5)
       c = gg(c, d, a, b, x[11],  9)
       b = gg(b, c, d, a, x[15], 13)
       a = hh(a, b, c, d, x[ 0],  3)
       d = hh(d, a, b, c, x[ 8],  9)
       c = hh(c, d, a, b, x[ 4], 11)
       b = hh(b, c, d, a, x[12], 15)
       a = hh(a, b, c, d, x[ 2],  3)
       d = hh(d, a, b, c, x[10],  9)
       c = hh(c, d, a, b, x[ 6], 11)
       b = hh(b, c, d, a, x[14], 15)
       a = hh(a, b, c, d, x[ 1],  3)
       d = hh(d, a, b, c, x[ 9],  9)
       c = hh(c, d, a, b, x[ 5], 11)
       b = hh(b, c, d, a, x[13], 15)
       a = hh(a, b, c, d, x[ 3],  3)
       d = hh(d, a, b, c, x[11],  9)
       c = hh(c, d, a, b, x[ 7], 11)
       b = hh(b, c, d, a, x[15], 15)
       context[0] += a
       context[1] += b
       context[2] += c
       context[3] += d
   }
   private fun ff(a: Int, b: Int, c: Int, d: Int, x: Int, s: Int): Int {
       val t = a + ((b and c) or (b.inv() and d)) + x
       return (t shl s) or (t ushr (32 - s))
   }
   private fun gg(a: Int, b: Int, c: Int, d: Int, x: Int, s: Int): Int {
       val t = a + ((b and (c or d)) or (c and d)) + x + 0x5a827999
       return (t shl s) or (t ushr (32 - s))
   }
   private fun hh(a: Int, b: Int, c: Int, d: Int, x: Int, s: Int): Int {
       val t = a + (b xor c xor d) + x + 0x6ed9eba1 
       return (t shl s) or (t ushr (32 - s))
   }

}

fun main(args: Array<String>) {

   val text  = "Rosetta Code"
   val bytes = text.toByteArray(Charsets.US_ASCII)
   val md: MessageDigest = MD4()
   val digest = md.digest(bytes)
   for (byte in digest) print("%02x".format(byte))
   println() 

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Lasso

<lang Lasso>cipher_digest('Rosetta Code', -digest='MD4')->encodeHex->asString</lang>

Output:
 A52BCFC6A0D0D300CDC5DDBFBEFE478B 

Lua

Works with: Lua 5.1.4
Library: LuaCrypto

(luarocks install LuaCrypto)

<lang Lua>#!/usr/bin/lua

require "crypto"

print(crypto.digest("MD4", "Rosetta Code"))</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Mathematica

<lang Mathemtica>Hash["Rosetta Code", "MD4", "HexString"]</lang>

a52bcfc6a0d0d300cdc5ddbfbefe478b

Nim

Library: OpenSSL

Compile with nim -d:ssl c md4.nim: <lang nim>import strutils

const MD4Len = 16

proc MD4(d: cstring, n: culong, md: cstring = nil): cstring {.cdecl, dynlib: "libssl.so", importc.}

proc MD4(s: string): string =

 result = ""
 var s = MD4(s.cstring, s.len.culong)
 for i in 0 .. < MD4Len:
   result.add s[i].BiggestInt.toHex(2).toLower

echo MD4("Rosetta Code")</lang>

PARI/GP

Build a MD4 plugin using Linux system library and PARI's function interface. (Linux solution)

<lang C>#include <pari/pari.h>

  1. include <openssl/md4.h>
  1. define HEX(x) (((x) < 10)? (x)+'0': (x)-10+'a')

/*

* PARI/GP func: MD4 hash
*
* gp code: install("plug_md4", "s", "MD4", "<library path>");
*/

GEN plug_md4(char *text) {

 char md[MD4_DIGEST_LENGTH];
 char hash[sizeof(md) * 2 + 1];
 int i;
 MD4((unsigned char*)text, strlen(text), (unsigned char*)md);
 for (i = 0; i < sizeof(md); i++) {
   hash[i+i]   = HEX((md[i] >> 4) & 0x0f);
   hash[i+i+1] = HEX(md[i] & 0x0f);
 }
 hash[sizeof(md) * 2] = 0;
 return strtoGENstr(hash);

}</lang>

Compile with: gcc -Wall -O2 -fPIC -shared md4.c -o libmd4.so -lcrypt -lpari

Load plugin from your home directory into PARI: <lang parigp>install("plug_md4", "s", "MD4", "~/libmd4.so");

MD4("Rosetta Code") </lang>

Output: "a52bcfc6a0d0d300cdc5ddbfbefe478b"


Perl

In-lining code from module Digest::Perl::MD4, lightly edited for clarity. <lang perl>sub md4(@) {

   my @input = grep { defined && length > 0 } split /(.{64})/s, join , @_;
   push @input,  if !@input || length($input[$#input]) >= 56;
   my @A = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476); # initial regs
   my @T = (0, 0x5A827999, 0x6ED9EBA1);
   my @L = qw(3 7 11 19 3 5 9 13 3 9 11 15);   # left rotate counts
   my @O = (1, 4, 4,                           # x stride for input index
            4, 1, 1,                           # y stride for input index
            0, 0, 1);                          # bitwise reverse both indexes
   my @I = map {
                   my $z   = int $_/16;
                   my $x   = $_%4;
                   my $y   = int $_%16/4;
                   ($x,$y) = (R($x),R($y)) if $O[6+$z];
                   $O[$z] * $x + $O[3+$z] * $y
               } 0..47;
   my ($a,$b,$c,$d);
   my($l,$p) = (0,0);
   foreach (@input) {
       my $r = length($_);
       $l += $r;
       $r++, $_.="\x80" if $r<64 && !$p++;
       my @W = unpack 'V16', $_ . "\0"x7;
       push @W, (0)x16 if @W < 16;
       $W[14] = $l*8 if $r < 57;              # add bit-length in low 32-bits
       ($a,$b,$c,$d) = @A;
       for (0..47) {
           my $z = int $_/16;
           $a = L($L[4*($_>>4) + $_%4],
                M(&{(sub{$b&$c|~$b&$d},       # F
                     sub{$b&$c|$b&$d|$c&$d},  # G
                     sub{$b^$c^$d}            # H
                    )[$z]}
                  + $a + $W[$I[$_]] + $T[$z]));
           ($a,$b,$c,$d) = ($d,$a,$b,$c);
       }
       my @v = ($a, $b, $c, $d);
       $A[$_] = M($A[$_] + $v[$_]) for 0..3;
   }
   pack 'V4', @A;

}

sub L { # left-rotate

   my ($n, $x) = @_;
   $x<<$n | 2**$n - 1 & $x>>(32-$n);

}

sub M { # mod 2**32

   no integer;
   my ($x) = @_;
   my $m = 1+0xffffffff;
   $x - $m * int $x/$m;

}

sub R { # reverse two bit number

   my $n = pop;
   ($n&1)*2 + ($n&2)/2;

}

sub md4_hex(@) { # convert to hexadecimal

 unpack 'H*', &md4;

}

print "Rosetta Code => " . md4_hex( "Rosetta Code" ) . "\n";</lang>

Output:
Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b

Perl 6

<lang perl6>sub md4($str) {

   my @buf = $str.ords;
   my $buflen = @buf.elems;
   my \mask = (1 +< 32) - 1;
   my &f = -> $x, $y, $z { ($x +& $y) +| ($x +^ mask) +& $z }
   my &g = -> $x, $y, $z { ($x +& $y) +| ($x +& $z) +| ($y +& $z) }
   my &h = -> $x, $y, $z { $x +^ $y +^ $z }
   my &r = -> $v, $s { (($v +< $s) +& mask) +| (($v +& mask) +> (32 - $s)) }
   sub pack-le (@a) {
       gather for @a -> $a,$b,$c,$d { take $d +< 24 + $c +< 16 + $b +< 8 + $a }
   }

   my ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;

   my $term = False;
   my $last = False;
   my $off = 0;
   repeat until $last {
       my @block = @buf[$off..$off+63]:v; $off += 64;

       my @x;
       given +@block {

when 64 { @x = pack-le @block; } when 56..63 { $term = True; @block.push(0x80); @block.push(slip 0 xx 63 - $_); @x = pack-le @block; } when 0..55 { @block.push($term ?? 0 !! 0x80); @block.push(slip 0 xx 55 - $_); @x = pack-le @block;

my $bit_len = $buflen +< 3; @x.push: $bit_len +& mask, $bit_len +> 32; $last = True; } default { die "oops"; } }

my ($aa, $bb, $cc, $dd) = $a, $b, $c, $d; for 0, 4, 8, 12 -> \i { $a = r($a + f($b, $c, $d) + @x[ i+0 ], 3); $d = r($d + f($a, $b, $c) + @x[ i+1 ], 7); $c = r($c + f($d, $a, $b) + @x[ i+2 ], 11); $b = r($b + f($c, $d, $a) + @x[ i+3 ], 19); } for 0, 1, 2, 3 -> \i { $a = r($a + g($b, $c, $d) + @x[ i+0 ] + 0x5a827999, 3); $d = r($d + g($a, $b, $c) + @x[ i+4 ] + 0x5a827999, 5); $c = r($c + g($d, $a, $b) + @x[ i+8 ] + 0x5a827999, 9); $b = r($b + g($c, $d, $a) + @x[ i+12] + 0x5a827999, 13); } for 0, 2, 1, 3 -> \i { $a = r($a + h($b, $c, $d) + @x[ i+0 ] + 0x6ed9eba1, 3); $d = r($d + h($a, $b, $c) + @x[ i+8 ] + 0x6ed9eba1, 9); $c = r($c + h($d, $a, $b) + @x[ i+4 ] + 0x6ed9eba1, 11); $b = r($b + h($c, $d, $a) + @x[ i+12] + 0x6ed9eba1, 15); } $a = ($a + $aa) +& mask; $b = ($b + $bb) +& mask; $c = ($c + $cc) +& mask; $d = ($d + $dd) +& mask;

   }

   sub b2l($n is copy) {

my $x = 0; for ^4 { $x +<= 8; $x += $n +& 0xff; $n +>= 8; } $x;

   }
   b2l($a) +< 96 +
   b2l($b) +< 64 +
   b2l($c) +< 32 +
   b2l($d);

}

sub MAIN {

   my $str = 'Rosetta Code';
   say md4($str).base(16).lc;

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Phix

Translation of: D
Translation of: Ruby

<lang Phix>-- -- demo\rosetta\md4.exw -- ==================== -- function r32(atom a)

   if a<0 then a+=#100000000 end if
   return remainder(a,#100000000)

end function

function rol(atom word, integer bits) -- left rotate the bits of a 32-bit number by the specified number of bits

   word = r32(word)    -- trim to a 32-bit uint again
   return r32(word*power(2,bits))+floor(word/power(2,32-bits))

end function

function f(atom x,y,z)

   return or_bits(and_bits(x,y),and_bits(not_bits(x),z))

end function

function g(atom x,y,z)

   return or_all({r32(and_bits(x,y)),and_bits(x,z),and_bits(y,z)})

end function

function h(atom x,y,z)

   return xor_bits(r32(xor_bits(x,y)),z)

end function

function md4(sequence data)

   integer bytes_to_add = 64-remainder(length(data)+9,64)
   if bytes_to_add=64 then bytes_to_add = 0 end if
   data = data&#80&repeat(0,bytes_to_add)&
          int_to_bytes(length(data)*8,8)

   atom a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476

   atom m64 = allocate(64,true)
   integer i
   for x=1 to length(data)-1 by 64 do
       poke(m64,data[x..x+63])
       sequence z = peek4u({m64,16})
       atom a2 = a, b2 = b, c2 = c, d2 = d
       for i=0 to 12 by 4 do
           a = rol(a + f(b, c, d) + z[i+1],  3)
           d = rol(d + f(a, b, c) + z[i+2],  7)
           c = rol(c + f(d, a, b) + z[i+3], 11)
           b = rol(b + f(c, d, a) + z[i+4], 19)
       end for
       for i=1 to 4 do
           a = rol(a + g(b, c, d) + z[i+0]  + 0x5a827999,  3)
           d = rol(d + g(a, b, c) + z[i+4]  + 0x5a827999,  5)
           c = rol(c + g(d, a, b) + z[i+8]  + 0x5a827999,  9)
           b = rol(b + g(c, d, a) + z[i+12] + 0x5a827999, 13)
       end for
       for j=1 to 4 do
           i = {1, 3, 2, 4}[j]
           a = rol(a + h(b, c, d) + z[i+0]  + 0x6ed9eba1,  3)
           d = rol(d + h(a, b, c) + z[i+8]  + 0x6ed9eba1,  9)
           c = rol(c + h(d, a, b) + z[i+4]  + 0x6ed9eba1, 11)
           b = rol(b + h(c, d, a) + z[i+12] + 0x6ed9eba1, 15)
       end for
       a = r32(a+a2)
       b = r32(b+b2)
       c = r32(c+c2)
       d = r32(d+d2)
   end for
   poke4(m64,{a,b,c,d})
   return peek({m64,16})

end function

function hexify(sequence s)

   for i=1 to length(s) do
       s[i] = sprintf("%02X",s[i])
   end for
   return join(s,"")

end function

?hexify(md4("Rosetta Code"))</lang>

Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"

PicoLisp

Library and implementation. <lang picolisp>(de *Md4-W .

  (1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
  1  5  9 13  2  6 10 14  3  7 11 15  4  8 12 16
  1  9  5 13  3 11  7 15  2 10  6 14  4 12  8 16 .))

(de *Md4-R1 . (3 7 11 19 .)) (de *Md4-R2 . (3 5 9 13 .)) (de *Md4-R3 . (3 9 11 15 .))

(de mod32 (N)

  (& N `(hex "FFFFFFFF")) )

(de not32 (N)

  (x| N `(hex "FFFFFFFF")) )

(de add32 @

  (mod32 (pass +)) )
  

(de leftRotate (X C)

  (| (mod32 (>> (- C) X)) (>> (- 32 C) X)) )
  

(de md4 (Str)

  (let Len (length Str)
     (setq Str
        (conc
           (need
              (- 8 (* 64 (/ (+ Len 1 8 63) 64)))  # Pad to 64-8 bytes
              (conc
                 (mapcar char (chop Str))   # Works only with ASCII characters
                 (cons `(hex "80")) )       # '1' bit
              0 )                           # Pad with '0'
           (make
              (setq Len (* 8 Len))
              (do 8
                 (link (& Len 255))
                 (setq Len (>> 8 Len )) ) ) ) ) )
  (let
     (H0 `(hex "67452301")
        H1 `(hex "EFCDAB89")
        H2 `(hex "98BADCFE")
        H3 `(hex "10325476") 
        R2 `(hex "5A827999")
        R3 `(hex "6ED9EBA1") )
     (while Str
        (let
           (A H0  B H1  C H2  D H3
              W (make
                   (do 16
                      (link
                         (apply |
                         (mapcar >> (0 -8 -16 -24) (cut 4 'Str)) ) ) ) ) )
           (for I 12
              (cond
                 ((>= 4 I)
                    (setq
                       A (leftRotate
                            (add32
                               A
                               (| (& B C) (& (not32 B) D))
                               (get W (pop '*Md4-W)) )
                            (pop '*Md4-R1) )
                       D (leftRotate
                            (add32
                               D
                               (| (& A B) (& (not32 A) C))
                               (get W (pop '*Md4-W)) )
                            (pop '*Md4-R1) )
                       C (leftRotate
                            (add32
                               C
                               (| (& D A) (& (not32 D) B))
                               (get W (pop '*Md4-W)) )
                            (pop '*Md4-R1) )
                       B (leftRotate
                            (add32
                               B
                               (| (& C D) (& (not32 C) A))
                               (get W (pop '*Md4-W)) )
                            (pop '*Md4-R1) ) ) )
                 ((>= 8 I)
                    (setq
                       A (leftRotate
                            (add32 
                               A
                               (|
                                  (& B (| C D))
                                  (& C D) )
                               (get W (pop '*Md4-W))
                               R2 )
                            (pop '*Md4-R2) )
                       D (leftRotate
                            (add32
                               D
                               (|
                                  (& A (| B C))
                                  (& B C) )
                               (get W (pop '*Md4-W))
                               R2 )       
                            (pop '*Md4-R2) )
                       C (leftRotate
                            (add32 
                               C
                               (|
                                  (& D (| A B))
                                  (& A B) ) 
                               (get W (pop '*Md4-W))
                               R2 )
                            (pop '*Md4-R2) )
                       B (leftRotate
                            (add32 
                               B
                               (|
                                  (& C (| D A))
                                  (& D A) )
                               (get W (pop '*Md4-W))
                               R2 )
                            (pop '*Md4-R2) ) ) )
                 (T
                    (setq
                       A (leftRotate
                            (add32
                               A
                               (x| B C D)
                               (get W (pop '*Md4-W))
                               R3 )
                            (pop '*Md4-R3) )
                       D (leftRotate
                            (add32
                               D
                               (x| A B C)
                               (get W (pop '*Md4-W))
                               R3 )
                            (pop '*Md4-R3) )
                       C (leftRotate
                            (add32
                               C
                               (x| D A B)
                               (get W (pop '*Md4-W))
                               R3 )
                            (pop '*Md4-R3) )
                       B (leftRotate
                            (add32 
                               B
                               (x| C D A)
                               (get W (pop '*Md4-W))
                               R3 )
                            (pop '*Md4-R3) ) ) ) ) )
              (setq
                 H0 (add32 H0 A)
                 H1 (add32 H1 B)
                 H2 (add32 H2 C)
                 H3 (add32 H3 D) ) ) )
     (make
        (for N (list H0 H1 H2 H3)
           (do 4
              (link (& N 255))
              (setq N (>> 8 N)) ) ) ) ) )
 

(let Str "Rosetta Code"

  (println
     (pack
        (mapcar
           '((B) (pad 2 (hex B)))
           (md4 Str) ) ) )
  (println
     (pack
        (mapcar
           '((B) (pad 2 (hex B)))
           (native 
              "libcrypto.so"
              "MD4"
              '(B . 16)
              Str
              (length Str)
              '(NIL (16)) ) ) ) ) )

(bye)</lang>

PHP

<lang php> echo hash('md4', "Rosetta Code"), "\n"; </lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b


Python

Use 'hashlib' from python's standard library.

Library: hashlib

<lang python>import hashlib print hashlib.new("md4",raw_input().encode('utf-16le')).hexdigest().upper()</lang>

Racket

<lang racket>

  1. lang racket

(require (planet soegaard/digest:1:2/digest)) (md4 #"Rosetta Code") </lang>

Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"

Ruby

Use 'openssl' from Ruby's standard library.

Library: OpenSSL

<lang ruby>require 'openssl' puts OpenSSL::Digest::MD4.hexdigest('Rosetta Code')</lang>

Implement MD4 in Ruby.

<lang ruby>require 'stringio'

  1. Calculates MD4 message digest of _string_. Returns binary digest.
  2. For hexadecimal digest, use +*md4(str).unpack('H*')+.

def md4(string)

 # functions
 mask = (1 << 32) - 1
 f = proc {|x, y, z| x & y | x.^(mask) & z}
 g = proc {|x, y, z| x & y | x & z | y & z}
 h = proc {|x, y, z| x ^ y ^ z}
 r = proc {|v, s| (v << s).&(mask) | (v.&(mask) >> (32 - s))}

 # initial hash
 a, b, c, d = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476

 bit_len = string.size << 3
 string += "\x80"
 while (string.size % 64) != 56
   string += "\0"
 end
 string = string.force_encoding('ascii-8bit') + [bit_len & mask, bit_len >> 32].pack("V2")

 if string.size % 64 != 0
   fail "failed to pad to correct length"
 end

 io = StringIO.new(string)
 block = ""

 while io.read(64, block)
   x = block.unpack("V16")
   
   # Process this block.
   aa, bb, cc, dd = a, b, c, d
   [0, 4, 8, 12].each {|i|
     a = r[a + f[b, c, d] + x[i],  3]; i += 1
     d = r[d + f[a, b, c] + x[i],  7]; i += 1
     c = r[c + f[d, a, b] + x[i], 11]; i += 1
     b = r[b + f[c, d, a] + x[i], 19]
   }
   [0, 1, 2, 3].each {|i|
     a = r[a + g[b, c, d] + x[i] + 0x5a827999,  3]; i += 4
     d = r[d + g[a, b, c] + x[i] + 0x5a827999,  5]; i += 4
     c = r[c + g[d, a, b] + x[i] + 0x5a827999,  9]; i += 4
     b = r[b + g[c, d, a] + x[i] + 0x5a827999, 13]
   }
   [0, 2, 1, 3].each {|i|
     a = r[a + h[b, c, d] + x[i] + 0x6ed9eba1,  3]; i += 8
     d = r[d + h[a, b, c] + x[i] + 0x6ed9eba1,  9]; i -= 4
     c = r[c + h[d, a, b] + x[i] + 0x6ed9eba1, 11]; i += 8
     b = r[b + h[c, d, a] + x[i] + 0x6ed9eba1, 15]
   }
   a = (a + aa) & mask
   b = (b + bb) & mask
   c = (c + cc) & mask
   d = (d + dd) & mask
 end

 [a, b, c, d].pack("V4")

end

if __FILE__ == $0

 # Print an example MD4 digest.
 str = 'Rosetta Code'
 printf "%s:\n  %s\n", str, *md4(str).unpack('H*')

end</lang>

Output:
Rosetta Code:
  a52bcfc6a0d0d300cdc5ddbfbefe478b

Rust

<lang rust>// MD4, based on RFC 1186 and RFC 1320. // // https://www.ietf.org/rfc/rfc1186.txt // https://tools.ietf.org/html/rfc1320 //

use std::fmt::Write; use std::mem;

// Let not(X) denote the bit-wise complement of X. // Let X v Y denote the bit-wise OR of X and Y. // Let X xor Y denote the bit-wise XOR of X and Y. // Let XY denote the bit-wise AND of X and Y.

// f(X,Y,Z) = XY v not(X)Z fn f(x: u32, y: u32, z: u32) -> u32 {

   (x & y) | (!x & z)

}

// g(X,Y,Z) = XY v XZ v YZ fn g(x: u32, y: u32, z: u32) -> u32 {

   (x & y) | (x & z) | (y & z)

}

// h(X,Y,Z) = X xor Y xor Z fn h(x: u32, y: u32, z: u32) -> u32 {

   x ^ y ^ z

}

// Round 1 macro // Let [A B C D i s] denote the operation // A = (A + f(B,C,D) + X[i]) <<< s macro_rules! md4round1 {

   ( $a:expr, $b:expr, $c:expr, $d:expr, $i:expr, $s:expr, $x:expr) => {
       {
           // Rust defaults to non-overflowing arithmetic, so we need to specify wrapping add.
           $a = ($a.wrapping_add( f($b, $c, $d) ).wrapping_add( $x[$i] ) ).rotate_left($s);
       }
   };

}

// Round 2 macro // Let [A B C D i s] denote the operation // A = (A + g(B,C,D) + X[i] + 5A827999) <<< s . macro_rules! md4round2 {

   ( $a:expr, $b:expr, $c:expr, $d:expr, $i:expr, $s:expr, $x:expr) => {
       {
           $a = ($a.wrapping_add( g($b, $c, $d)).wrapping_add($x[$i]).wrapping_add(0x5a827999_u32)).rotate_left($s);
       }
   };

}

// Round 3 macro // Let [A B C D i s] denote the operation // A = (A + h(B,C,D) + X[i] + 6ED9EBA1) <<< s . macro_rules! md4round3 {

   ( $a:expr, $b:expr, $c:expr, $d:expr, $i:expr, $s:expr, $x:expr) => {
       {
           $a = ($a.wrapping_add(h($b, $c, $d)).wrapping_add($x[$i]).wrapping_add(0x6ed9eba1_u32)).rotate_left($s);
       }
   };

}

fn convert_byte_vec_to_u32(mut bytes: Vec<u8>) -> Vec<u32> {

   bytes.shrink_to_fit();
   let num_bytes = bytes.len();
   let num_words = num_bytes / 4;
   unsafe {
       let words = Vec::from_raw_parts(bytes.as_mut_ptr() as *mut u32, num_words, num_words);
       mem::forget(bytes);
       words
   }

}

// Returns a 128-bit MD4 hash as an array of four 32-bit words. // Based on RFC 1186 from https://www.ietf.org/rfc/rfc1186.txt fn md4<T: Into<Vec<u8>>>(input: T) -> [u32; 4] {

   let mut bytes = input.into().to_vec();
   let initial_bit_len = (bytes.len() << 3) as u64;
   // Step 1. Append padding bits
   // Append one '1' bit, then append 0 ≤ k < 512 bits '0', such that the resulting message
   // length in bis is congruent to 448 (mod 512).
   // Since our message is in bytes, we use one byte with a set high-order bit (0x80) plus
   // a variable number of zero bytes.
   // Append zeros
   // Number of padding bytes needed is 448 bits (56 bytes) modulo 512 bits (64 bytes)
   bytes.push(0x80_u8);
   while (bytes.len() % 64) != 56 {
       bytes.push(0_u8);
   }
   // Everything after this operates on 32-bit words, so reinterpret the buffer.
   let mut w = convert_byte_vec_to_u32(bytes);
   // Step 2. Append length
   // A 64-bit representation of b (the length of the message before the padding bits were added)
   // is appended to the result of the previous step, low-order bytes first.
   w.push(initial_bit_len as u32); // Push low-order bytes first
   w.push((initial_bit_len >> 32) as u32);
   // Step 3. Initialize MD buffer
   let mut a = 0x67452301_u32;
   let mut b = 0xefcdab89_u32;
   let mut c = 0x98badcfe_u32;
   let mut d = 0x10325476_u32;
   // Step 4. Process message in 16-word blocks
   let n = w.len();
   for i in 0..n / 16 {
       // Select the next 512-bit (16-word) block to process.
       let x = &w[i * 16..i * 16 + 16];
       let aa = a;
       let bb = b;
       let cc = c;
       let dd = d;
       // [Round 1]
       md4round1!(a, b, c, d, 0, 3, x);  // [A B C D 0 3]
       md4round1!(d, a, b, c, 1, 7, x);  // [D A B C 1 7]
       md4round1!(c, d, a, b, 2, 11, x); // [C D A B 2 11]
       md4round1!(b, c, d, a, 3, 19, x); // [B C D A 3 19]
       md4round1!(a, b, c, d, 4, 3, x);  // [A B C D 4 3]
       md4round1!(d, a, b, c, 5, 7, x);  // [D A B C 5 7]
       md4round1!(c, d, a, b, 6, 11, x); // [C D A B 6 11]
       md4round1!(b, c, d, a, 7, 19, x); // [B C D A 7 19]
       md4round1!(a, b, c, d, 8, 3, x);  // [A B C D 8 3]
       md4round1!(d, a, b, c, 9, 7, x);  // [D A B C 9 7]
       md4round1!(c, d, a, b, 10, 11, x);// [C D A B 10 11]
       md4round1!(b, c, d, a, 11, 19, x);// [B C D A 11 19]
       md4round1!(a, b, c, d, 12, 3, x); // [A B C D 12 3]
       md4round1!(d, a, b, c, 13, 7, x); // [D A B C 13 7]
       md4round1!(c, d, a, b, 14, 11, x);// [C D A B 14 11]
       md4round1!(b, c, d, a, 15, 19, x);// [B C D A 15 19]
       // [Round 2]
       md4round2!(a, b, c, d, 0, 3, x);  //[A B C D 0  3]
       md4round2!(d, a, b, c, 4, 5, x);  //[D A B C 4  5]
       md4round2!(c, d, a, b, 8, 9, x);  //[C D A B 8  9]
       md4round2!(b, c, d, a, 12, 13, x);//[B C D A 12 13]
       md4round2!(a, b, c, d, 1, 3, x);  //[A B C D 1  3]
       md4round2!(d, a, b, c, 5, 5, x);  //[D A B C 5  5]
       md4round2!(c, d, a, b, 9, 9, x);  //[C D A B 9  9]
       md4round2!(b, c, d, a, 13, 13, x);//[B C D A 13 13]
       md4round2!(a, b, c, d, 2, 3, x);  //[A B C D 2  3]
       md4round2!(d, a, b, c, 6, 5, x);  //[D A B C 6  5]
       md4round2!(c, d, a, b, 10, 9, x); //[C D A B 10 9]
       md4round2!(b, c, d, a, 14, 13, x);//[B C D A 14 13]
       md4round2!(a, b, c, d, 3, 3, x);  //[A B C D 3  3]
       md4round2!(d, a, b, c, 7, 5, x);  //[D A B C 7  5]
       md4round2!(c, d, a, b, 11, 9, x); //[C D A B 11 9]
       md4round2!(b, c, d, a, 15, 13, x);//[B C D A 15 13]
       // [Round 3]
       md4round3!(a, b, c, d, 0, 3, x);  //[A B C D 0  3]
       md4round3!(d, a, b, c, 8, 9, x);  //[D A B C 8  9]
       md4round3!(c, d, a, b, 4, 11, x); //[C D A B 4  11]
       md4round3!(b, c, d, a, 12, 15, x);//[B C D A 12 15]
       md4round3!(a, b, c, d, 2, 3, x);  //[A B C D 2  3]
       md4round3!(d, a, b, c, 10, 9, x); //[D A B C 10 9]
       md4round3!(c, d, a, b, 6, 11, x); //[C D A B 6  11]
       md4round3!(b, c, d, a, 14, 15, x);//[B C D A 14 15]
       md4round3!(a, b, c, d, 1, 3, x);  //[A B C D 1  3]
       md4round3!(d, a, b, c, 9, 9, x);  //[D A B C 9  9]
       md4round3!(c, d, a, b, 5, 11, x); //[C D A B 5  11]
       md4round3!(b, c, d, a, 13, 15, x);//[B C D A 13 15]
       md4round3!(a, b, c, d, 3, 3, x);  //[A B C D 3  3]
       md4round3!(d, a, b, c, 11, 9, x); //[D A B C 11 9]
       md4round3!(c, d, a, b, 7, 11, x); //[C D A B 7  11]
       md4round3!(b, c, d, a, 15, 15, x);//[B C D A 15 15]
       a = a.wrapping_add(aa);
       b = b.wrapping_add(bb);
       c = c.wrapping_add(cc);
       d = d.wrapping_add(dd);
   }
   // Step 5. Output
   // The message digest produced as output is A, B, C, D. That is, we begin with the low-order
   // byte of A, and end with the high-order byte of D.
   [u32::from_be(a), u32::from_be(b), u32::from_be(c), u32::from_be(d)]

}

fn digest_to_str(digest: &[u32]) -> String {

   let mut s = String::new();
   for &word in digest {
       write!(&mut s, "{:08x}", word).unwrap();
   }
   s

}

fn main() {

   let val = "Rosetta Code";
   println!("md4(\"{}\") = {}", val, digest_to_str(&md4(val)));

}</lang>

Output:
md4("Rosetta Code") = a52bcfc6a0d0d300cdc5ddbfbefe478b

Scala

Library: Scala

<lang Scala>import org.bouncycastle.crypto.digests.MD4Digest

object RosettaRIPEMD160 extends App {

 val (raw, messageDigest) = ("Rosetta Code".getBytes("US-ASCII"), new MD4Digest())
 messageDigest.update(raw, 0, raw.length)
 val out = Array.fill[Byte](messageDigest.getDigestSize())(0)
 messageDigest.doFinal(out, 0)
 assert(out.map("%02x".format(_)).mkString == "a52bcfc6a0d0d300cdc5ddbfbefe478b")
 import scala.compat.Platform.currentTime
 println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]")

}</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

 include "msgdigest.s7i";

const proc: main is func

 begin
   writeln(hex(md4("Rosetta Code")));
 end func;</lang>
Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Sidef

Translation of: Perl

<lang ruby>var digest = frequire('Digest::MD4'); say digest.md4_hex('Rosetta Code');</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

Tcl

Library: Tcllib (Package: md4)

<lang tcl>package require md4

  1. Use -hex option for hexadecimal output instead of binary

puts [md4::md4 -hex "Rosetta Code"]</lang>

Output:
A52BCFC6A0D0D300CDC5DDBFBEFE478B