MD4: Difference between revisions
(Added C implementation) |
SqrtNegInf (talk | contribs) m (→{{header|Perl 6}}: 'push' requires 'slip') |
||
Line 578: | Line 578: | ||
$term = True; |
$term = True; |
||
@block.push(0x80); |
@block.push(0x80); |
||
@block.push(0 xx 63 - $_); |
@block.push(slip 0 xx 63 - $_); |
||
@x = pack-le @block; |
@x = pack-le @block; |
||
} |
} |
||
when 0..55 { |
when 0..55 { |
||
@block.push($term ?? 0 !! 0x80); |
@block.push($term ?? 0 !! 0x80); |
||
@block.push(0 xx 55 - $_); |
@block.push(slip 0 xx 55 - $_); |
||
@x = pack-le @block; |
@x = pack-le @block; |
||
Revision as of 15:25, 18 January 2016
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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.
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 */
- include <stdlib.h>
- include <string.h>
- 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=";
- define F(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
- define G(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
- define H(X,Y,Z) ((X)^(Y)^(Z))
- define LEFTROTATE(A,N) ((A)<<(N))|((A)>>(32-(N)))
- define MD4ROUND1(a,b,c,d,x,s) a += F(b,c,d) + x; a = LEFTROTATE(a, s);
- define MD4ROUND2(a,b,c,d,x,s) a += G(b,c,d) + x + (uint32_t)0x5A827999; a = LEFTROTATE(a, s);
- 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
Clojure
<lang clojure>(use 'pandect.core) (md4 "Rosetta Code")</lang>
- Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"
Common Lisp
<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.
<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
Haskell
<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
Java
<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
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
Lasso
<lang Lasso>cipher_digest('Rosetta Code', -digest='MD4')->encodeHex->asString</lang>
- Output:
A52BCFC6A0D0D300CDC5DDBFBEFE478B
Lua
<lang Lua>#!/usr/bin/lua
require "crypto"
print(crypto.digest("MD4", "Rosetta Code"))</lang>
- Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b
Nim
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>
Perl
<lang Perl>#!/usr/bin/perl use strict ; use warnings ; use Digest::MD4 qw( md4_hex ) ;
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
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.
<lang python>import hashlib print hashlib.new("md4",raw_input().encode('utf-16le')).hexdigest().upper()</lang>
Racket
<lang racket>
- lang racket
(require (planet soegaard/digest:1:2/digest)) (md4 #"Rosetta Code") </lang>
- Output:
"a52bcfc6a0d0d300cdc5ddbfbefe478b"
Ruby
Use 'openssl' from Ruby's standard library.
<lang ruby>require 'openssl' puts OpenSSL::Digest::MD4.hexdigest('Rosetta Code')</lang>
Implement MD4 in Ruby.
<lang ruby>require 'stringio'
- Calculates MD4 message digest of _string_. Returns binary digest.
- 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
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
<lang ruby>var digest = frequire('Digest::MD4'); say digest.md4_hex('Rosetta Code');</lang>
- Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b
Tcl
<lang tcl>package require md4
- Use -hex option for hexadecimal output instead of binary
puts [md4::md4 -hex "Rosetta Code"]</lang>
- Output:
A52BCFC6A0D0D300CDC5DDBFBEFE478B