MD4: Difference between revisions

10,939 bytes added ,  5 months ago
m
m (→‎{{header|Phix}}: added syntax colouring, marked p2js incompatible)
m (→‎{{header|Wren}}: Minor tidy)
 
(19 intermediate revisions by 6 users not shown)
Line 11:
=={{header|Ada}}==
{{libheader|CryptAda}}
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
with CryptAda.Digests.Message_Digests.MD4;
Line 44:
Ada.Text_IO.Put_Line
("""" & Text & """: " & CryptAda.Utils.Format.To_Hex_String (Hashes.Get_Bytes (Hash)));
end RC_MD4;</langsyntaxhighlight>
{{out}}
<pre>"Rosetta Code": A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>
Line 50:
=={{header|AutoHotkey}}==
Source: [https://github.com/jNizM/AutoHotkey_Scripts/tree/master/Functions/Checksums MD4 @github] by jNizM
<langsyntaxhighlight AutoHotkeylang="autohotkey">str := "Rosetta Code"
MsgBox, % "String:`n" (str) "`n`nMD4:`n" MD4(str)
 
Line 101:
StrPut(string, &data, floor(length / chrlength), encoding)
return CalcAddrHash(&data, length, algid, hash, hashlength)
}</langsyntaxhighlight>
{{out}}
<pre>String: Rosetta Code
MD4: A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<syntaxhighlight 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</syntaxhighlight>
{{out}}
<pre>Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">
<lang C>
/*
*
Line 358 ⟶ 515:
setMD4Registers(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
}
</syntaxhighlight>
</lang>
{{Out}}
<langsyntaxhighlight Clang="c">printf("%s\n", MD4("Rosetta Code", 12));</langsyntaxhighlight>
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 411 ⟶ 568:
}
static void Main() { Console.WriteLine("Rosetta Code".Md4Hash()); }
}</langsyntaxhighlight>
{{out}}
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
 
class MD4 {
public:
MD4() {
engine_reset();
}
 
std::vector<int8_t> engine_digest(const std::string& text) {
engine_update(string_to_byte_vector(text), 0, text.length());
 
const int32_t buffer_index = static_cast<int32_t>(count % BLOCK_LENGTH);
const int32_t padding_length = ( buffer_index < 56 ) ? 56 - buffer_index : 120 - buffer_index;
 
std::vector<int8_t> tail(padding_length + 8, 0);
tail[0] = static_cast<int8_t>(0x80);
 
for ( int32_t i = 0; i < 8; ++i ) {
tail[padding_length + i] = static_cast<int8_t>(unsigned_right_shift(count * 8, 8 * i));
}
 
engine_update(tail, 0, tail.size());
 
std::vector<int8_t> result(16, 0);
for ( int32_t i = 0; i < 4; ++i ) {
for ( int32_t j = 0; j < 4; ++j ) {
result[i * 4 + j] = static_cast<int8_t>(unsigned_right_shift(context[i], 8 * j));
}
}
 
engine_reset();
return result;
}
 
private:
void engine_update(const std::vector<int8_t>& message_bytes,
const int32_t& offset, const int32_t& message_length) {
if ( offset < 0 || message_length < 0
|| (int64_t) offset + message_length > (int64_t) message_bytes.size() ) {
throw std::invalid_argument("Incorrect arguments for function engine_update");
}
 
int32_t buffer_index = static_cast<int32_t>(count % BLOCK_LENGTH);
count += message_length;
const int32_t partial_length = BLOCK_LENGTH - buffer_index;
int32_t i = 0;
 
if ( message_length >= partial_length ) {
for ( int32_t j = 0; j < partial_length; ++j ) {
buffer[buffer_index + j] = message_bytes[offset + j];
}
transform(buffer, 0);
i = partial_length;
while ( i + BLOCK_LENGTH - 1 < message_length ) {
transform(message_bytes, offset + i);
i += BLOCK_LENGTH;
}
buffer_index = 0;
}
 
if ( i < message_length ) {
for ( int32_t j = 0; j < message_length - i; ++j ) {
buffer[buffer_index + j] = message_bytes[offset + i + j];
}
}
}
 
void transform(const std::vector<int8_t>& buffer, int32_t offset) {
for ( int32_t i = 0; i < 16; ++i ) {
extra[i] = ( ( buffer[offset + 0] & 0xff ) ) |
( ( buffer[offset + 1] & 0xff ) << 8 ) |
( ( buffer[offset + 2] & 0xff ) << 16 ) |
( ( buffer[offset + 3] & 0xff ) << 24 );
offset += 4;
}
 
int32_t a = context[0];
int32_t b = context[1];
int32_t c = context[2];
int32_t d = context[3];
 
for ( const int32_t& i : { 0, 4, 8, 12 } ) {
a = ff(a, b, c, d, extra[i + 0], 3);
d = ff(d, a, b, c, extra[i + 1], 7);
c = ff(c, d, a, b, extra[i + 2], 11);
b = ff(b, c, d, a, extra[i + 3], 19);
}
 
for ( const int32_t& i : { 0, 1, 2, 3 } ) {
a = gg(a, b, c, d, extra[i + 0], 3);
d = gg(d, a, b, c, extra[i + 4], 5);
c = gg(c, d, a, b, extra[i + 8], 9);
b = gg(b, c, d, a, extra[i + 12], 13);
}
 
for ( const int32_t& i : { 0, 2, 1, 3 } ) {
a = hh(a, b, c, d, extra[i + 0], 3);
d = hh(d, a, b, c, extra[i + 8], 9);
c = hh(c, d, a, b, extra[i + 4], 11);
b = hh(b, c, d, a, extra[i + 12], 15);
}
 
context[0] += a;
context[1] += b;
context[2] += c;
context[3] += d;
}
 
void engine_reset() {
count = 0;
context.assign(4, 0);
context[0] = 0x67452301;
context[1] = 0xefcdab89;
context[2] = 0x98badcfe;
context[3] = 0x10325476;
extra.assign(16, 0);
buffer.assign(BLOCK_LENGTH, 0);
}
 
std::vector<int8_t> string_to_byte_vector(const std::string& text) {
std::vector<int8_t> bytes;
bytes.reserve(text.size());
 
std::transform(text.begin(), text.end(), std::back_inserter(bytes),
[](char ch){ return static_cast<int8_t>(ch); });
 
return bytes;
}
 
int32_t unsigned_right_shift(const int32_t& base, const int32_t& shift) {
if ( shift < 0 || shift >= 32 || base == 0 ) {
return 0;
}
return ( base > 0 ) ? base >> shift : static_cast<uint32_t>(base) >> shift;
}
 
int32_t rotate(const int32_t& t, const int32_t& s) {
return ( t << s ) | unsigned_right_shift(t, 32 - s);
}
 
int32_t ff(const int32_t& a, const int32_t& b, const int32_t& c,
const int32_t& d, const int32_t& x, const int32_t& s) {
return rotate(a + ( ( b & c ) | ( ~b & d ) ) + x, s);
}
 
int32_t gg(const int32_t& a, const int32_t& b, const int32_t& c,
const int32_t& d, const int32_t& x, const int32_t& s) {
return rotate(a + ( ( b & ( c | d ) ) | ( c & d ) ) + x + 0x5A827999, s);
}
 
int32_t hh(const int32_t& a, const int32_t& b, const int32_t& c,
const int32_t& d, const int32_t& x, const int32_t& s) {
return rotate(a + ( b ^ c ^ d ) + x + 0x6ED9EBA1, s);
}
 
uint64_t count;
std::vector<int32_t> context;
std::vector<int32_t> extra;
std::vector<int8_t> buffer;
 
const int32_t BLOCK_LENGTH = 64;
};
 
int main() {
MD4 md4;
std::vector<int8_t> result = md4.engine_digest("Rosetta Code");
 
for ( const int8_t& bb : result ) {
std::cout << std::hex << std::setfill('0') << std::setw(2) << ( bb & 0xff );
}
std::cout << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
a52bcfc6a0d0d300cdc5ddbfbefe478b
</pre>
 
=={{header|Clojure}}==
{{libheader|pandect}}
<langsyntaxhighlight lang="clojure">(use 'pandect.core)
(md4 "Rosetta Code")</langsyntaxhighlight>
 
{{Out}}
Line 425 ⟶ 767:
=={{header|Common Lisp}}==
{{libheader|Ironclad}}
<langsyntaxhighlight lang="lisp">(ql:quickload 'ironclad)
(defun md4 (str)
(ironclad:byte-array-to-hex-string
Line 431 ⟶ 773:
(ironclad:ascii-string-to-byte-array str))))
 
(md4 "Rosetta Code")</langsyntaxhighlight>
 
{{Out}}
Line 439 ⟶ 781:
A short but not efficient implementation.
{{trans|Ruby}}
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.range;
 
ubyte[16] md4(const(ubyte)[] inData) pure nothrow {
Line 485 ⟶ 827:
void main() {
writefln("%(%02x%)", "Rosetta Code".representation.md4);
}</langsyntaxhighlight>
{{out}}
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
Line 492 ⟶ 834:
{{libheader| DCPmd4}}
Thanks for David Barton for DCPcrypt v2.0 library, and StephenGenusa for store and share in github [https://github.com/StephenGenusa/DCPCrypt].
<syntaxhighlight lang="delphi">
<lang Delphi>
program CalcMD4;
 
Line 522 ⟶ 864:
Writeln(MD4('Rosetta Code'));
readln;
end.</langsyntaxhighlight>
{{out}}
<pre>A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>
Line 530 ⟶ 872:
<code>md4.el</code> by Taro Kawagishi, originally from [http://git.chise.org/elisp/flim/ FLIM] and included in recent Emacs, is an Elisp implementation of the MD4 algorithm. Its <code>md4</code> function returns the checksum as 16 binary bytes. <code>encode-hex-string</code> from <code>hex-util.el</code> can convert that to a hex string if desired.
 
<langsyntaxhighlight Lisplang="lisp">(require 'md4)
(require 'hex-util)
(let* ((s "Rosetta Code")
(m (md4 s (length s)))) ;; m = 16 binary bytes
(require 'hex-util)
(encode-hex-string m))
=>
"a52bcfc6a0d0d300cdc5ddbfbefe478b"</langsyntaxhighlight>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">
-module(md4).
-export([md4/0]).
Line 546 ⟶ 888:
<<MD4:128>> = crypto:md4("Rosetta Code"),
io:fwrite("Rosetta Code => ~.16B~n",[MD4]).
</syntaxhighlight>
</lang>
<pre>
Rosetta Code => A52BCFC6A0D0D300CDC5DDBFBEFE478B
</pre>
 
=={{header|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>
{{out}}
<pre>Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
 
=={{header|Go}}==
{{libheader|Go sub-repositories}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 720 ⟶ 906:
h.Write([]byte("Rosetta Code"))
fmt.Printf("%x\n", h.Sum(nil))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 728 ⟶ 914:
=={{header|Haskell}}==
{{libheader|Cryptonite}}
<langsyntaxhighlight lang="haskell">#!/usr/bin/env runhaskell
 
import Data.ByteString.Char8 (pack)
Line 736 ⟶ 922:
main :: IO ()
main = print . md4 . pack . unwords =<< getArgs
where md4 x = hash x :: Digest MD4</langsyntaxhighlight>
{{out}}
<pre>
Line 744 ⟶ 930:
 
=={{header|J}}==
<langsyntaxhighlight lang="j"> require 'ide/qt'
gethash_jqtide_ 'MD4';'Rosetta Code'
a52bcfc6a0d0d300cdc5ddbfbefe478b</langsyntaxhighlight>
 
=={{header|Java}}==
{{libheader|BouncyCastle}}
<langsyntaxhighlight lang="java">import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.util.encoders.Hex;
 
Line 765 ⟶ 951:
System.out.println();
}
}</langsyntaxhighlight>
{{out}}
<pre>
a52bcfc6a0d0d300cdc5ddbfbefe478b
</pre>
 
===Without external libraries===
<syntaxhighlight lang="java">
import java.util.Arrays;
import java.util.List;
 
public final class MD4Task {
public static void main(String[] aArgs) {
String text = "Rosetta Code";
MD4 md4 = new MD4();
byte[] result = md4.engineDigest(text);
StringBuilder stringBuilder = new StringBuilder();
for ( byte bb : result ) {
stringBuilder.append(String.format("%02x", bb));
}
System.out.println(stringBuilder.toString());
}
}
final class MD4 {
public MD4() {
engineReset();
}
 
public byte[] engineDigest(String aText) {
engineUpdate(aText.getBytes(), 0, aText.length());
final int bufferIndex = (int) ( count % BLOCK_LENGTH );
final int paddingLength = ( bufferIndex < 56 ) ? 56 - bufferIndex : 120 - bufferIndex;
 
byte[] tail = new byte[paddingLength + 8];
tail[0] = (byte) 0x80;
for ( int i = 0; i < 8; i++ ) {
tail[paddingLength + i] = (byte) ( ( count * 8 ) >>> ( 8 * i ) );
}
engineUpdate(tail, 0, tail.length);
 
byte[] result = new byte[16];
for ( int i = 0; i < 4; i++ ) {
for ( int j = 0; j < 4; j++ ) {
result[i * 4 + j] = (byte) ( context[i] >>> ( 8 * j ) );
}
}
 
engineReset();
return result;
}
private void engineUpdate(byte[] aMessageBytes, int aOffset, int aMessageLength) {
if ( aOffset < 0 || aMessageLength < 0 || (long) aOffset + aMessageLength > (long) aMessageBytes.length ) {
throw new ArrayIndexOutOfBoundsException("Incorrect arguments for method engineUpdate");
}
int bufferIndex = (int) ( count % BLOCK_LENGTH );
count += aMessageLength;
final int partialLength = BLOCK_LENGTH - bufferIndex;
int i = 0;
if ( aMessageLength >= partialLength ) {
System.arraycopy(aMessageBytes, aOffset, buffer, bufferIndex, partialLength);
transform(buffer, 0);
i = partialLength;
while ( i + BLOCK_LENGTH - 1 < aMessageLength ) {
transform(aMessageBytes, aOffset + i);
i += BLOCK_LENGTH;
}
bufferIndex = 0;
}
if ( i < aMessageLength ) {
System.arraycopy(aMessageBytes, aOffset + i, buffer, bufferIndex, aMessageLength - i);
}
}
private void transform (byte[] aBuffer, int aOffset) {
for ( int i = 0; i < 16; i++ ) {
extra[i] = ( ( aBuffer[aOffset++] & 0xff ) ) |
( ( aBuffer[aOffset++] & 0xff ) << 8 ) |
( ( aBuffer[aOffset++] & 0xff ) << 16 ) |
( ( aBuffer[aOffset++] & 0xff ) << 24 );
}
int a = context[0];
int b = context[1];
int c = context[2];
int d = context[3];
for ( int i : List.of( 0, 4, 8, 12 ) ) {
a = ff(a, b, c, d, extra[i + 0], 3);
d = ff(d, a, b, c, extra[i + 1], 7);
c = ff(c, d, a, b, extra[i + 2], 11);
b = ff(b, c, d, a, extra[i + 3], 19);
}
for ( int i : List.of( 0, 1, 2, 3 ) ) {
a = gg(a, b, c, d, extra[i + 0], 3);
d = gg(d, a, b, c, extra[i + 4], 5);
c = gg(c, d, a, b, extra[i + 8], 9);
b = gg(b, c, d, a, extra[i + 12], 13);
}
for ( int i : List.of( 0, 2, 1, 3 ) ) {
a = hh(a, b, c, d, extra[i + 0], 3);
d = hh(d, a, b, c, extra[i + 8], 9);
c = hh(c, d, a, b, extra[i + 4], 11);
b = hh(b, c, d, a, extra[i + 12], 15);
}
 
context[0] += a;
context[1] += b;
context[2] += c;
context[3] += d;
}
private void engineReset() {
count = 0;
context[0] = 0x67452301;
context[1] = 0xefcdab89;
context[2] = 0x98badcfe;
context[3] = 0x10325476;
Arrays.fill(extra, 0);
Arrays.fill(buffer, (byte) 0);
}
private static int rotate(int t, int s) {
return t << s | t >>> ( 32 - s );
}
private static int ff(int a, int b, int c, int d, int x, int s) {
return rotate(a + ( ( b & c ) | ( ~b & d ) ) + x, s);
}
private static int gg(int a, int b, int c, int d, int x, int s) {
return rotate(a + ( ( b & ( c | d ) ) | ( c & d ) ) + x + 0x5A827999, s);
}
private static int hh(int a, int b, int c, int d, int x, int s) {
return rotate(a + ( b ^ c ^ d ) + x + 0x6ED9EBA1, s);
}
private static final int BLOCK_LENGTH = 64;
private long count;
private int[] context = new int[4];
private int[] extra = new int[16];
private byte[] buffer = new byte[BLOCK_LENGTH];
 
}
</syntaxhighlight>
{{ out }}
<pre>
a52bcfc6a0d0d300cdc5ddbfbefe478b
Line 772 ⟶ 1,118:
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">const md4func = () => {
 
const hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
Line 983 ⟶ 1,329:
 
const md4 = md4func();
console.log(md4.hex_md4('Rosetta Code'));</langsyntaxhighlight>
{{out}}
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
Line 989 ⟶ 1,335:
=={{header|Julia}}==
[https://github.com/staticfloat/Nettle.jl Nettle.jl] provides a variety of cryptographic functions including the <tt>MD4</tt> hash.
<syntaxhighlight lang="julia">
<lang Julia>
using Nettle
 
Line 999 ⟶ 1,345:
 
println("\"", msg, "\" => ", h)
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,008 ⟶ 1,354:
=={{header|Kotlin}}==
This is a translation of the Java code [http://www.java2s.com/Code/Java/Security/ImplementstheMD4messagedigestalgorithminJava.htm here]. In the interests of conciseness, I have removed the comments from the Kotlin version:
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.security.MessageDigest
Line 1,175 ⟶ 1,521:
for (byte in digest) print("%02x".format(byte))
println()
}</langsyntaxhighlight>
 
{{out}}
Line 1,183 ⟶ 1,529:
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">cipher_digest('Rosetta Code', -digest='MD4')->encodeHex->asString</langsyntaxhighlight>
{{out}}
<pre> A52BCFC6A0D0D300CDC5DDBFBEFE478B </pre>
Line 1,192 ⟶ 1,538:
{{libheader|LuaCrypto}} ([http://mkottman.github.io/luacrypto/ luarocks install LuaCrypto])
 
<langsyntaxhighlight Lualang="lua">#!/usr/bin/lua
 
require "crypto"
 
print(crypto.digest("MD4", "Rosetta Code"))</langsyntaxhighlight>
 
{{out}}
Line 1,202 ⟶ 1,548:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathemticalang="mathematica">Hash["Rosetta Code", "MD4", "HexString"]</langsyntaxhighlight>
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
 
=={{header|Nim}}==
{{libheader|OpenSSL}}
<langsyntaxhighlight lang="nim">import strutils
 
const MD4Len = 16
Line 1,219 ⟶ 1,565:
result.add s[i].BiggestInt.toHex(2).toLower
 
echo MD4("Rosetta Code")</langsyntaxhighlight>
 
{{out}}
Line 1,228 ⟶ 1,574:
Build a MD4 plugin using Linux system library and PARI's function interface. (Linux solution)
 
<langsyntaxhighlight Clang="c">#include <pari/pari.h>
#include <openssl/md4.h>
 
Line 1,254 ⟶ 1,600:
 
return strtoGENstr(hash);
}</langsyntaxhighlight>
 
Compile with: gcc -Wall -O2 -fPIC -shared md4.c -o libmd4.so -lcrypt -lpari
 
Load plugin from your home directory into PARI:
<langsyntaxhighlight lang="parigp">install("plug_md4", "s", "MD4", "~/libmd4.so");
 
MD4("Rosetta Code") </langsyntaxhighlight>
 
Output: "a52bcfc6a0d0d300cdc5ddbfbefe478b"
Line 1,267 ⟶ 1,613:
=={{header|Perl}}==
In-lining code from module [https://metacpan.org/pod/Digest::Perl::MD4 Digest::Perl::MD4], lightly edited for clarity.
<langsyntaxhighlight lang="perl">sub md4 :prototype(@) {
my @input = grep { defined && length > 0 } split /(.{64})/s, join '', @_;
push @input, '' if !@input || length($input[$#input]) >= 56;
Line 1,328 ⟶ 1,674:
}
 
sub md4_hex :prototype(@) { # convert to hexadecimal
unpack 'H*', &md4;
}
 
print "Rosetta Code => " . md4_hex( "Rosetta Code" ) . "\n";</langsyntaxhighlight>
{{out}}
<pre>Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
Line 1,339 ⟶ 1,685:
{{trans|D}}
{{trans|Ruby}}
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\md4.exw
Line 1,424 ⟶ 1,770:
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,431 ⟶ 1,777:
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">
echo hash('md4', "Rosetta Code"), "\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
Line 1,439 ⟶ 1,785:
=={{header|PicoLisp}}==
Library and implementation.
<langsyntaxhighlight 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
Line 1,614 ⟶ 1,960:
'(NIL (16)) ) ) ) ) )
 
(bye)</langsyntaxhighlight>
 
=={{header|Python}}==
Use 'hashlib' from python's standard library.
{{libheader|hashlib}}
<langsyntaxhighlight lang="python">import hashlib
print hashlib.new("md4",raw_input().encode('utf-16le')).hexdigest().upper()</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require (planet soegaard/digest:1:2/digest))
(md4 #"Rosetta Code")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,635 ⟶ 1,981:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>sub md4($str) {
my @buf8 $buf .= new: $str.ordsencode;
my $buflenbuf-length = @$buf.elems;
$buf.push: 0x80;
$buf.push: 0 until ($buf - (448 div 8)) %% (512 div 8);
# raku serializes in little endian by default
$buf.write-uint64: $buf.elems, $buf-length*8;
 
my \mask(&f, =&g, (1&h, +< 32&r) -= 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 },
# for some reason we have to type v here
my &r = -> $v, $s { (($v +< $s) +& mask) +| (($v +& mask) +> (32 - $s)) }
-> uint32 $v, $s { $v +< $s +| $v +> (32 - $s) }
 
my uint32 ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
sub pack-le (@a) {
gather for @a -> $a,$b,$c,$d { take $d +< 24 + $c +< 16 + $b +< 8 + $a }
}
loop (my $pos = 0; $pos < $buf.elems; $pos+=64) {
my ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
my ($aa, $bb, $cc, $dd) = $a, $b, $c, $d;
for 0, 4, 8, 12 -> $i {
my $term = False;
$a = r($a + f($b, $c, $d) + $buf.read-uint32($pos+($i+0)*4), 3);
my $last = False;
$d = r($d + f($a, $b, $c) + $buf.read-uint32($pos+($i+1)*4), 7);
my $off = 0;
$c = r($c + f($d, $a, $b) + $buf.read-uint32($pos+($i+2)*4), 11);
repeat until $last {
my @block $b = @buf[r($off..$offb +63]:v; f($offc, $d, $a) += 64$buf.read-uint32($pos+($i+3)*4), 19);
}
myfor @x;0, 1, 2, 3 -> $i {
$a = r($a + g($b, $c, $d) + $buf.read-uint32($pos+($i+0 )*4) + 0x5a827999, 3);
given +@block {
$d = r($d + g($a, $b, $c) + $buf.read-uint32($pos+($i+4 )*4) + 0x5a827999, 5);
when 64 {
$c = r($c + g($d, $a, $b) + $buf.read-uint32($pos+($i+8 )*4) + 0x5a827999, 9);
@x = pack-le @block;
$b = r($b + g($c, $d, $a) + $buf.read-uint32($pos+($i+12)*4) + 0x5a827999, 13);
}
when 56..63 { }
$termfor =0, 2, 1, 3 -> $i True;{
$a = r($a + h($b, $c, $d) + $buf.read-uint32($pos+($i+0 )*4) + 0x6ed9eba1, 3);
@block.push(0x80);
$d = r($d + h($a, $b, $c) + $buf.read-uint32($pos+($i+4 )*4) + 0x6ed9eba1, 9);
@block.push(slip 0 xx 63 - $_);
$c = r($c + h($d, $a, $b) + $buf.read-uint32($pos+($i+8 )*4) + 0x6ed9eba1, 11);
@x = pack-le @block;
$b = r($b + h($c, $d, $a) + $buf.read-uint32($pos+($i+12)*4) + 0x6ed9eba1, 15);
}
when 0..55 { }
@block.push($terma,$b,$c,$d) ??Z[+=] 0 !! 0x80($aa,$bb,$cc,$dd);
@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;
}
reduce { $^buf.write-uint32: $buf.elems, $^x; $buf }, buf8.new, $a, $b, $c, $d;
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);
}
CHECK {
sub MAIN {
use Test;
my $str = 'Rosetta Code';
plan 1;
say md4($str).base(16).lc;
is md4('Rosetta Code').list.fmt('%02X'), 'A5 2B CF C6 A0 D0 D3 00 CD C5 DD BF BE FE 47 8B';
}</lang>
}</syntaxhighlight>
{{out}}
<pre>1..1
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
ok 1 -
</pre>
 
=={{header|Ruby}}==
Use 'openssl' from Ruby's standard library.
{{libheader|OpenSSL}}
<langsyntaxhighlight lang="ruby">require 'openssl'
puts OpenSSL::Digest::MD4.hexdigest('Rosetta Code')</langsyntaxhighlight>
 
Implement MD4 in Ruby.
 
<langsyntaxhighlight lang="ruby">require 'stringio'
 
# Calculates MD4 message digest of _string_. Returns binary digest.
Line 1,803 ⟶ 2,107:
str = 'Rosetta Code'
printf "%s:\n %s\n", str, *md4(str).unpack('H*')
end</langsyntaxhighlight>
{{out}}
<pre>Rosetta Code:
Line 1,809 ⟶ 2,113:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">// MD4, based on RFC 1186 and RFC 1320.
//
// https://www.ietf.org/rfc/rfc1186.txt
Line 2,008 ⟶ 2,312:
let val = "Rosetta Code";
println!("md4(\"{}\") = {}", val, digest_to_str(&md4(val)));
}</langsyntaxhighlight>
 
{{out}}
Line 2,017 ⟶ 2,321:
=={{header|Scala}}==
{{libheader|Scala}}
<langsyntaxhighlight Scalalang="scala">import org.bouncycastle.crypto.digests.MD4Digest
 
object RosettaRIPEMD160 extends App {
Line 2,028 ⟶ 2,332:
import scala.compat.Platform.currentTime
println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]")
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "msgdigest.s7i";
 
Line 2,037 ⟶ 2,341:
begin
writeln(hex(md4("Rosetta Code")));
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,046 ⟶ 2,350:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">var digest = frequire('Digest::MD4');
say digest.md4_hex('Rosetta Code');</langsyntaxhighlight>
{{out}}
<pre>
Line 2,055 ⟶ 2,359:
=={{header|Tcl}}==
{{tcllib|md4}}
<langsyntaxhighlight lang="tcl">package require md4
 
# Use -hex option for hexadecimal output instead of binary
puts [md4::md4 -hex "Rosetta Code"]</langsyntaxhighlight>
{{out}}
<pre>A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>
Line 2,065 ⟶ 2,369:
{{trans|D}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var toBytes = Fn.new { |val|
Line 2,157 ⟶ 2,461:
var digest = md4.call(s)
Fmt.print("$s <== '$0s'", Fmt.v("xz", 2, digest, 0, "", ""), s)
}</langsyntaxhighlight>
 
{{out}}
9,482

edits