MD4

From Rosetta Code
Revision as of 19:51, 8 January 2013 by rosettacode>Markhobley (placed task requirement at top and removed unneeded description)
MD4 is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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 thst 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.

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

Go

Works with: Go 1

<lang go>package main

import (

   "code.google.com/p/go.crypto/md4"
   "fmt"

)

func main() {

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

}</lang>

Output:
a52bcfc6a0d0d300cdc5ddbfbefe478b

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

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>


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
 io = StringIO.new(string)
 block = ""
 term = false  # appended "\x80" in second-last block?
 last = false  # last block?
 until last
   # Read next block of 16 words (64 bytes, 512 bits).
   io.read(64, block) or (
     # Work around a bug in Rubinius 1.2.4. At eof,
     # MRI and JRuby already replace block with "".
     block.replace("")
   )
   # Unpack block into 32-bit words "V".
   case len = block.length
   when 64
     # Unpack 16 words.
     x = block.unpack("V16")
   when 56..63
     # Second-last block: append padding, unpack 16 words.
     block.concat("\x80"); term = true
     block.concat("\0" * (63 - len))
     x = block.unpack("V16")
   when 0..55
     # Last block: append padding, unpack 14 words.
     block.concat(term ? "\0" : "\x80")
     block.concat("\0" * (55 - len))
     x = block.unpack("V14")
     # Append bit length, 2 words.
     bit_len = string.length << 3
     x.push(bit_len & mask, bit_len >> 32)
     last = true
   else
     fail "impossible"
   end
   # 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

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