MD5

From Rosetta Code
Task
MD5
You are encouraged to solve this task according to the task description, using any language you may know.

Encode a string using an MD5 algorithm. The algorithm can be found on the wiki.

Ada

Works with: GNAT

<lang ada>with Ada.Text_IO; use Ada.Text_IO; with GNAT.MD5;

procedure MD5_Digest is begin

  Put(GNAT.MD5.Digest("Foo bar baz"));

end MD5_Digest;</lang>

AutoHotkey

Search autohotkey.com: [1]

Regular version

Source: AutoHotkey forum by SKAN
<lang autohotkey> data := "abc" MsgBox % MD5(data,StrLen(data)) ; 900150983cd24fb0d6963f7d28e17f72

MD5( ByRef V, L=0 ) {

VarSetCapacity( MD5_CTX,104,0 ), DllCall( "advapi32\MD5Init", Str,MD5_CTX ) 
DllCall( "advapi32\MD5Update", Str,MD5_CTX, Str,V, UInt,L ? L : VarSetCapacity(V) ) 
DllCall( "advapi32\MD5Final", Str,MD5_CTX ) 
Loop % StrLen( Hex:="123456789ABCDEF0" ) 
 N := NumGet( MD5_CTX,87+A_Index,"Char"), MD5 .= SubStr(Hex,N>>4,1) . SubStr(Hex,N&15,1) 

Return MD5 } } </lang>

Native implementation

Source: AutoHotkey forum by Laszlo
<lang autohotkey>

GLOBAL CONSTANTS r[64], k[64]

r = 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 , 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20 , 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23 , 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 StringSplit r, r, `, r0 := 7 Loop 64

  i := A_Index-1, k%i% := floor(abs(sin(A_Index)) * 2**32) 
TEST CASES

MsgBox % MD5(x:="", 0) ; d41d8cd98f00b204e9800998ecf8427e MsgBox % MD5(x:="a", StrLen(x)) ; 0cc175b9c0f1b6a831c399e269772661 MsgBox % MD5(x:="abc", StrLen(x)) ; 900150983cd24fb0d6963f7d28e17f72 MsgBox % MD5(x:="message digest", StrLen(x)) ; f96b697d7cb7938d525a2f31aaf161d0 MsgBox % MD5(x:="abcdefghijklmnopqrstuvwxyz", StrLen(x))

c3fcd3d76192e4007dfb496cca67e13b

MsgBox % MD5(x:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", StrLen(x))

d174ab98d277d9f5a5611c2c9f419d9f

MsgBox % MD5(x:="12345678901234567890123456789012345678901234567890123456789012345678901234567890", StrLen(x))

57edf4a22be3c955ac49da2e2107b67a

MsgBox % MD5(x:="The quick brown fox jumps over the lazy dog", StrLen(x))

9e107d9d372bb6826bd81d3542a419d6

MsgBox % MD5(x:="The quick brown fox jumps over the lazy cog", StrLen(x))

1055d3e698d289f2af8663725127bd4b

MD5(ByRef Buf, L) { ; Binary buffer, Length in bytes

  Static P, Q, N, i, a,b,c,d, t, h0,h1,h2,h3, y = 0xFFFFFFFF 
  h0 := 0x67452301, h1 := 0xEFCDAB89, h2 := 0x98BADCFE, h3 := 0x10325476 
  N := ceil((L+9)/64)*64 ; padded length (100..separator, 8B length) 
  VarSetCapacity(Q,N,0)  ; room for padded data 
  P := &Q ; pointer 
  DllCall("RtlMoveMemory", UInt,P, UInt,&Buf, UInt,L) ; copy data 
  DllCall("RtlFillMemory", UInt,P+L, UInt,1, UInt,0x80) ; pad separator 
  DllCall("ntdll.dll\RtlFillMemoryUlong",UInt,P+N-8,UInt,4,UInt,8*L) ; at end: length in bits < 512 MB 
  Loop % N//64 { 
     Loop 16 
        i := A_Index-1, w%i% := *P | *(P+1)<<8 | *(P+2)<<16 | *(P+3)<<24, P += 4 
     a := h0, b := h1, c := h2, d := h3 
     Loop 64 { 
        i := A_Index-1 
        If i < 16 
            f := (b & c) | (~b & d), g := i 
        Else If i < 32 
            f := (d & b) | (~d & c), g := 5*i+1 & 15 
        Else If i < 48 
            f := b ^ c ^ d,          g := 3*i+5 & 15 
        Else 
            f := c ^ (b | ~d),       g :=  7*i  & 15 
        t := d, d := c, c := b 
        b += rotate(a + f + k%i% + w%g%, r%i%) ; reduced to 32 bits later 
        a := t 
     } 
     h0 := h0+a & y, h1 := h1+b & y, h2 := h2+c & y, h3 := h3+d & y 
  } 
  Return hex(h0) . hex(h1) . hex(h2) . hex(h3) 

}

rotate(a,b) { ; 32-bit rotate a to left by b bits, bit32..63 garbage

  Return a << b | (a & 0xFFFFFFFF) >> (32-b) 

}

hex(x) {  ; 32-bit little endian hex digits

  SetFormat Integer, HEX 
  x += 0x100000000, x := SubStr(x,-1) . SubStr(x,8,2) . SubStr(x,6,2) . SubStr(x,4,2) 
  SetFormat Integer, DECIMAL 
  Return x 

} </lang>

C

Library: OpenSSL

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  3. include <openssl/md5.h>

const char *string = "The quick brown fox jumped over the lazy dog's back";

int main() {

 int i;
 unsigned char result[MD5_DIGEST_LENGTH];
 MD5(string, strlen(string), result);
 // output
 for(i = 0; i < MD5_DIGEST_LENGTH; i++)
   printf("%02x", result[i]);
 printf("\n");
 return EXIT_SUCCESS;

}</lang> Implementation of md5 <lang c>#include <stdlib.h>

  1. include <stdio.h>
  2. include <string.h>
  3. include <math.h>

typedef union uwb {

   unsigned w;
   unsigned char b[4];

} WBunion;

typedef unsigned Digest[4];

unsigned f0( unsigned abcd[] ){

   return ( abcd[1] & abcd[2]) | (~abcd[1] & abcd[3]);}

unsigned f1( unsigned abcd[] ){

   return ( abcd[3] & abcd[1]) | (~abcd[3] & abcd[2]);}

unsigned f2( unsigned abcd[] ){

   return  abcd[1] ^ abcd[2] ^ abcd[3];}

unsigned f3( unsigned abcd[] ){

   return abcd[2] ^ (abcd[1] |~ abcd[3]);}

typedef unsigned (*DgstFctn)(unsigned a[]);

unsigned *calcKs( unsigned *k) {

   double s, pwr;
   int i;
   pwr = pow( 2, 32);
   for (i=0; i<64; i++) {
       s = fabs(sin(1+i));
       k[i] = (unsigned)( s * pwr );
   }
   return k;

}

// ROtate v Left by amt bits unsigned rol( unsigned v, short amt ) {

   unsigned  msk1 = (1<<amt) -1;
   return ((v>>(32-amt)) & msk1) | ((v<<amt) & ~msk1);

}

unsigned *md5( const char *msg, int mlen) {

   static Digest h0 = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 };

// static Digest h0 = { 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210 };

   static DgstFctn ff[] = { &f0, &f1, &f2, &f3 };
   static short M[] = { 1, 5, 3, 7 };
   static short O[] = { 0, 1, 5, 0 };
   static short rot0[] = { 7,12,17,22};
   static short rot1[] = { 5, 9,14,20};
   static short rot2[] = { 4,11,16,23};
   static short rot3[] = { 6,10,15,21};
   static short *rots[] = {rot0, rot1, rot2, rot3 };
   static unsigned kspace[64];
   static unsigned *k;
   static Digest h;
   Digest abcd;
   DgstFctn fctn;
   short m, o, g;
   unsigned f;
   short *rotn;
   union {
       unsigned w[16];
       char     b[64];
   }mm;
   int os = 0;
   int grp, grps, q, p;
   unsigned char *msg2;
   if (k==NULL) k= calcKs(kspace);
   for (q=0; q<4; q++) h[q] = h0[q];   // initialize
   {
       grps  = 1 + (mlen+3)/64;
       msg2 = (unsigned char *)malloc( 64*grps);
       memcpy( msg2, msg, mlen);
       msg2[mlen] = (unsigned char)0x80;  
       q = mlen + 1;
       while (q < 64*grps){ msg2[q] = 0; q++ ; }
       {

// unsigned char t;

           WBunion u;
           u.w = 8*mlen;

// t = u.b[0]; u.b[0] = u.b[3]; u.b[3] = t; // t = u.b[1]; u.b[1] = u.b[2]; u.b[2] = t;

           q -= 8;
           memcpy(msg2+q, &u.w, 4 );
       }
   }
   for (grp=0; grp<grps; grp++)
   {
       memcpy( mm.b, msg2+os, 64);
       for(q=0;q<4;q++) abcd[q] = h[q];
       for (p = 0; p<4; p++) {
           fctn = ff[p];
           rotn = rots[p];
           m = M[p]; o= O[p];
           for (q=0; q<16; q++) {
               g = (m*q + o) % 16;
               f = abcd[1] + rol( abcd[0]+ fctn(abcd) + k[q+16*p] + mm.w[g], rotn[q%4]);
               abcd[0] = abcd[3];
               abcd[3] = abcd[2];
               abcd[2] = abcd[1];
               abcd[1] = f;
           }
       }
       for (p=0; p<4; p++)
           h[p] += abcd[p];
       os += 64;
   }
   return h;

}

int main( int argc, char *argv[] ) {

   int j,k;
   const char *msg = "The quick brown fox jumps over the lazy dog.";
   unsigned *d = md5(msg, strlen(msg));
   WBunion u;
   printf("= 0x");
   for (j=0;j<4; j++){
       u.w = d[j];
       for (k=0;k<4;k++) printf("%02x",u.b[k]);
   }
   printf("\n");
   return 0;

}</lang>

C#

<lang csharp>using System.Text; using System.Security.Cryptography;

byte[] data = Encoding.ASCII.GetBytes("The quick brown fox jumped over the lazy dog's back"); byte[] hash = MD5.Create().ComputeHash(data); Console.WriteLine(BitConverter.ToString(hash).Replace("-", "").ToLower());</lang>

D

Library: Tango

<lang d>module md5test ; import tango.io.digest.Md5 ; import tango.io.Stdout ; void main(char[][] args) {

 auto md5 = new Md5() ;
 for(int i = 1 ; i < args.length ; i++){
   md5.update(args[i]) ;
   Stdout.formatln("[{}]=>\n[{}]", args[i], md5.hexDigest()) ;
 }

}</lang> Sample output:

>md5test "The quick brown fox jumped over the lazy dog's back"
[The quick brown fox jumped over the lazy dog's back]=>
[e38ca1d920c4b8b8d3946b2c72f01680]

Clojure

<lang lisp> (apply str

 (map (partial format "%02x")
   (.digest (doto (java.security.MessageDigest/getInstance "MD5")
                  .reset
                  (.update (.getBytes "The quick brown fox jumps over the lazy dog"))))))

</lang>

Common Lisp

This one uses a library, but if you want to see how it's implemented, press M-x slime-edit-definition and go to md5:md5sum-stream.

<lang lisp>(require #+sbcl 'sb-md5 #-sbcl 'md5)

(defvar +letters+ "0123456789abcdef")

(defun octets->letters (octet-vector)

 (with-output-to-string (stream)
   (loop for i across octet-vector
         do (flet ((foo (x) (aref +letters+ (ldb (byte x (- x 4)) i))))
              (princ (foo 8) stream)
              (princ (foo 4) stream)))))

(defun md5 (string)

 (octets->letters #+sbcl (sb-md5:md5sum-string string)
                  #-sbcl (with-input-from-string (stream string)

(md5:md5sum-stream stream))))

 CL-USER> (md5 "foo")
 "acbd18db4cc2f85cedef654fccc4a4d8"</lang>

E

Works with: E-on-Java
Translation of: Java

(with modifications)

<lang e>def makeMessageDigest := <import:java.security.makeMessageDigest> def sprintf := <import:java.lang.makeString>.format

def digest := makeMessageDigest.getInstance("MD5") \

 .digest("The quick brown fox jumped over the lazy dog's back".getBytes("iso-8859-1"))

for b in digest {

 print(sprintf("%02x", [b]))

} println()</lang>

Erlang

By default, Erlang's crypto functions like md5 return a binary value rather than a hex string. We have two write our own function to translate it: <lang Erlang> -module(tests). -export([md5/1]).

md5(S) ->

string:to_upper(
 lists:flatten([io_lib:format("~2.16.0b",[N]) || <<N>> <= erlang:md5(S)])
).

</lang> Testing it: <lang erlang> 1> c(tests). {ok,tests} 2> tests:md5("The quick brown fox jumped over the lazy dog's back"). "E38CA1D920C4B8B8D3946B2C72F01680" </lang>

Factor

Using builtin library:

USING: kernel strings io checksums checksums.md5 ;
"The quick brown fox jumps over the lazy dog"

md5 checksum-bytes hex-string print

Forth

include ffl/md5.fs

\ Create a MD5 variable md1 in the dictionary

md5-create md1

\ Update the variable with data

s" The quick brown fox jumps over the lazy dog" md1 md5-update

\ Finish the MD5 calculation resulting in four unsigned 32 bit words
\ on the stack representing the hash value

md1 md5-finish

\ Convert the hash value to a hex string and print it

md5+to-string type cr

Haskell

Use modules nano-MD5 and ByteString from HackageDB <lang Haskell>import Data.Digest.OpenSSL.MD5(md5sum);import Data.ByteString(pack);import Data.Char(ord)

main = do

putStrLn $ md5sum $ pack
   $ map (fromIntegral.ord) "The quick brown fox jumped over the lazy dog's back"</lang>

Use in GHCi:

*Main> main
e38ca1d920c4b8b8d3946b2c72f01680

J

Using the md5 script from the convert/misc addon package: <lang j>

  require 'convert/misc/md5'
  md5 'The quick brown fox jumped over the lazy dogs back'

e38ca1d920c4b8b8d3946b2c72f01680 </lang>

Java

Modified from mindprod's Java Glossary: <lang java>import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;

/**

* Test MD5 digest computation
*
* @author Roedy Green
* @version 1.0
* @since 2004-06-07
*/

public final class MD5{ public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException{ byte[] theTextToDigestAsBytes= "The quick brown fox jumped over the lazy dog's back" .getBytes("8859_1"); MessageDigest md= MessageDigest.getInstance("MD5"); md.update(theTextToDigestAsBytes); byte[] digest= md.digest();

// dump out the hash for(byte b: digest){ System.out.printf("%02X", b & 0xff); } System.out.println(); } }</lang> Other options for digest algorithms (to replace "MD5" in the example above) include: MD2, SHA-1, SHA-256, SHA-384, and SHA-512. Other encoding options (to replace "8859_1" in the example above) include: UTF-8, UTF-16, and ASCII.

Mathematica

Mathematica has built-in function Hash and FileHash, it should be noted that Hash["hello","MD5"] would give the MD5 of ""hello"" in stead of "hello". This is done because it wants to distinguish between the variable hello and the string "hello". A workaround for getting MD5's from strings would be: <lang Mathematica>

StringHash[string_String]:=Module[{stream=OpenWrite[],file,hash},
 WriteString[stream,string];
 file=Close[stream];
 hash=FileHash[file,"MD5"];
 DeleteFile[file];
 hash
]

</lang> Example: <lang Mathematica>

StringHash["The quick brown fox jumped over the lazy dog's back"] // BaseForm[#, 16] &

</lang> gives back: <lang Mathematica>

e38ca1d920c4b8b8d3946b2c72f01680

</lang>

Modula-3

Modula-3's standard library (libm3) does not have code for MD5, so it has to be implemented. <lang modula3>INTERFACE MD5;

IMPORT Word;

TYPE Digest = ARRAY [0..15] OF CHAR; TYPE Buffer = ARRAY [0..63] OF CHAR;

TYPE T = RECORD

 state: ARRAY [0..3] OF Word.T;
 count: ARRAY [0..1] OF Word.T;
 buffer: Buffer;

END;

PROCEDURE Init(VAR md5ctx: T); PROCEDURE Update(VAR md5ctx: T; input: TEXT); PROCEDURE Final(VAR md5ctx: T): Digest; PROCEDURE ToText(hash: Digest): TEXT;

END MD5.</lang> <lang modula3>MODULE MD5;

IMPORT Word, Text, Fmt;

CONST S11 = 7; S12 = 12; S13 = 17; S14 = 22;

     S21 = 5; S22 = 9; S23 = 14; S24 = 20;
     S31 = 4; S32 = 11; S33 = 16; S34 = 23;
     S41 = 6; S42 = 10; S43 = 15; S44 = 21;
     pad1 = "\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
     pad2 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
     pad3 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
     pad4 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
     padding = pad1 & pad2 & pad3 & pad4;

PROCEDURE Init(VAR md5ctx: T) =

 BEGIN
   <*ASSERT Word.Size = 32*>
   md5ctx.count[0] := 0;
   md5ctx.count[1] := 0;
   md5ctx.state[0] := 16_67452301;
   md5ctx.state[1] := 16_efcdab89;
   md5ctx.state[2] := 16_98badcfe;
   md5ctx.state[3] := 16_10325476;
 END Init;

PROCEDURE Transform(VAR state: ARRAY [0..3] OF Word.T;

                   VAR input: Buffer) =
 VAR a, b, c, d: INTEGER;
     x: ARRAY [0..15] OF INTEGER;
 PROCEDURE Decode(VAR x: ARRAY [0..15] OF INTEGER;
                  VAR input: Buffer) =
   BEGIN
     FOR i := 0 TO 15 DO
       x[i] := Word.Insert(x[i], ORD(input[4*i+0]), 0, 8);
       x[i] := Word.Insert(x[i], ORD(input[4*i+1]), 8, 8);
       x[i] := Word.Insert(x[i], ORD(input[4*i+2]), 16, 8);
       x[i] := Word.Insert(x[i], ORD(input[4*i+3]), 24, 8);
     END;
   END Decode;
 PROCEDURE FF(VAR a: INTEGER; b, c, d, x, s, ac: INTEGER) =
   PROCEDURE F(x, y, z: INTEGER): INTEGER =
     BEGIN
       RETURN Word.Or(Word.And(x, y), Word.And(Word.Not(x), z));
     END F;
   BEGIN
     a := b + Word.Rotate(a + F(b, c, d) + x + ac, s);
   END FF;
 PROCEDURE GG(VAR a: INTEGER; b, c, d, x, s, ac: INTEGER) =
   PROCEDURE G(x, y, z: INTEGER): INTEGER =
     BEGIN
       RETURN Word.Or(Word.And(x, z), Word.And(y, Word.Not(z)));
     END G;
   BEGIN
     a := b + Word.Rotate(a + G(b, c, d) + x + ac, s);
   END GG;
 PROCEDURE HH(VAR a: INTEGER; b, c, d, x, s, ac: INTEGER) =
   PROCEDURE H(x, y, z: INTEGER): INTEGER =
     BEGIN
       RETURN Word.Xor(x, Word.Xor(y,z));
     END H;
   BEGIN
     a := b + Word.Rotate(a + H(b, c, d) + x + ac, s);
   END HH;
 PROCEDURE II(VAR a: INTEGER; b, c, d, x, s, ac: INTEGER) =
   PROCEDURE I(x, y, z: INTEGER): INTEGER =
     BEGIN
       RETURN Word.Xor(y, Word.Or(x, Word.Not(z)))
     END I;
   BEGIN
     a := b + Word.Rotate(a + I(b, c, d) + x + ac, s)
   END II;
 BEGIN
   Decode(x, input);
   
   a := state[0];
   b := state[1];
   c := state[2];
   d := state[3];
   
   (* Round 1 *)
   FF(a, b, c, d, x[ 0], S11, 16_d76aa478); (* 1 *)
   FF(d, a, b, c, x[ 1], S12, 16_e8c7b756); (* 2 *)
   FF(c, d, a, b, x[ 2], S13, 16_242070db); (* 3 *)
   FF(b, c, d, a, x[ 3], S14, 16_c1bdceee); (* 4 *)
   FF(a, b, c, d, x[ 4], S11, 16_f57c0faf); (* 5 *)
   FF(d, a, b, c, x[ 5], S12, 16_4787c62a); (* 6 *)
   FF(c, d, a, b, x[ 6], S13, 16_a8304613); (* 7 *)
   FF(b, c, d, a, x[ 7], S14, 16_fd469501); (* 8 *)
   FF(a, b, c, d, x[ 8], S11, 16_698098d8); (* 9 *)
   FF(d, a, b, c, x[ 9], S12, 16_8b44f7af); (* 10 *)
   FF(c, d, a, b, x[10], S13, 16_ffff5bb1); (* 11 *)
   FF(b, c, d, a, x[11], S14, 16_895cd7be); (* 12 *)
   FF(a, b, c, d, x[12], S11, 16_6b901122); (* 13 *)
   FF(d, a, b, c, x[13], S12, 16_fd987193); (* 14 *)
   FF(c, d, a, b, x[14], S13, 16_a679438e); (* 15 *)
   FF(b, c, d, a, x[15], S14, 16_49b40821); (* 16 *)
   (* Round 2 *)
   GG(a, b, c, d, x[ 1], S21, 16_f61e2562); (* 17 *)
   GG(d, a, b, c, x[ 6], S22, 16_c040b340); (* 18 *)
   GG(c, d, a, b, x[11], S23, 16_265e5a51); (* 19 *)
   GG(b, c, d, a, x[ 0], S24, 16_e9b6c7aa); (* 20 *)
   GG(a, b, c, d, x[ 5], S21, 16_d62f105d); (* 21 *)
   GG(d, a, b, c, x[10], S22, 16_02441453); (* 22 *)
   GG(c, d, a, b, x[15], S23, 16_d8a1e681); (* 23 *)
   GG(b, c, d, a, x[ 4], S24, 16_e7d3fbc8); (* 24 *)
   GG(a, b, c, d, x[ 9], S21, 16_21e1cde6); (* 25 *)
   GG(d, a, b, c, x[14], S22, 16_c33707d6); (* 26 *)
   GG(c, d, a, b, x[ 3], S23, 16_f4d50d87); (* 27 *)
   GG(b, c, d, a, x[ 8], S24, 16_455a14ed); (* 28 *)
   GG(a, b, c, d, x[13], S21, 16_a9e3e905); (* 29 *)
   GG(d, a, b, c, x[ 2], S22, 16_fcefa3f8); (* 30 *)
   GG(c, d, a, b, x[ 7], S23, 16_676f02d9); (* 31 *)
   GG(b, c, d, a, x[12], S24, 16_8d2a4c8a); (* 32 *)
   (* Round 3 *)
   HH(a, b, c, d, x[ 5], S31, 16_fffa3942); (* 33 *)
   HH(d, a, b, c, x[ 8], S32, 16_8771f681); (* 34 *)
   HH(c, d, a, b, x[11], S33, 16_6d9d6122); (* 35 *)
   HH(b, c, d, a, x[14], S34, 16_fde5380c); (* 36 *)
   HH(a, b, c, d, x[ 1], S31, 16_a4beea44); (* 37 *)
   HH(d, a, b, c, x[ 4], S32, 16_4bdecfa9); (* 38 *)
   HH(c, d, a, b, x[ 7], S33, 16_f6bb4b60); (* 39 *)
   HH(b, c, d, a, x[10], S34, 16_bebfbc70); (* 40 *)
   HH(a, b, c, d, x[13], S31, 16_289b7ec6); (* 41 *)
   HH(d, a, b, c, x[ 0], S32, 16_eaa127fa); (* 42 *)
   HH(c, d, a, b, x[ 3], S33, 16_d4ef3085); (* 43 *)
   HH(b, c, d, a, x[ 6], S34, 16_04881d05); (* 44 *)
   HH(a, b, c, d, x[ 9], S31, 16_d9d4d039); (* 45 *)
   HH(d, a, b, c, x[12], S32, 16_e6db99e5); (* 46 *)
   HH(c, d, a, b, x[15], S33, 16_1fa27cf8); (* 47 *)
   HH(b, c, d, a, x[ 2], S34, 16_c4ac5665); (* 48 *)
   (* Round 4 *)
   II(a, b, c, d, x[ 0], S41, 16_f4292244); (* 49 *)
   II(d, a, b, c, x[ 7], S42, 16_432aff97); (* 50 *)
   II(c, d, a, b, x[14], S43, 16_ab9423a7); (* 51 *)
   II(b, c, d, a, x[ 5], S44, 16_fc93a039); (* 52 *)
   II(a, b, c, d, x[12], S41, 16_655b59c3); (* 53 *)
   II(d, a, b, c, x[ 3], S42, 16_8f0ccc92); (* 54 *)
   II(c, d, a, b, x[10], S43, 16_ffeff47d); (* 55 *)
   II(b, c, d, a, x[ 1], S44, 16_85845dd1); (* 56 *)
   II(a, b, c, d, x[ 8], S41, 16_6fa87e4f); (* 57 *)
   II(d, a, b, c, x[15], S42, 16_fe2ce6e0); (* 58 *)
   II(c, d, a, b, x[ 6], S43, 16_a3014314); (* 59 *)
   II(b, c, d, a, x[13], S44, 16_4e0811a1); (* 60 *)
   II(a, b, c, d, x[ 4], S41, 16_f7537e82); (* 61 *)
   II(d, a, b, c, x[11], S42, 16_bd3af235); (* 62 *)
   II(c, d, a, b, x[ 2], S43, 16_2ad7d2bb); (* 63 *)
   II(b, c, d, a, x[ 9], S44, 16_eb86d391); (* 64 *)
   state[0] := Word.Plus(state[0], a);
   state[1] := Word.Plus(state[1], b);
   state[2] := Word.Plus(state[2], c);
   state[3] := Word.Plus(state[3], d);
 END Transform;

PROCEDURE Update(VAR md5ctx: T; input: TEXT) =

 VAR index, i, j, partLen: Word.T;
     locbuff: Buffer;
 BEGIN
   index := Word.And(Word.Shift(md5ctx.count[0], -3), 16_3F);
   md5ctx.count[0] := 
       Word.Plus(md5ctx.count[0], Word.Shift(Text.Length(input), 3));
   IF md5ctx.count[0] < Text.Length(input) THEN
     INC(md5ctx.count[1]);
   END;
   md5ctx.count[1] := md5ctx.count[1] + Word.Shift(Text.Length(input), -29);
   partLen := 64 - index;
   IF Text.Length(input) >= partLen THEN
     FOR i := index TO 63 DO
       md5ctx.buffer[i] := Text.GetChar(input, i-index);
     END;
     Transform(md5ctx.state, md5ctx.buffer);
     i := partLen;
     WHILE (i + 63) < Text.Length(input) DO
       FOR j := 0 TO 63 DO
         locbuff[j] := Text.GetChar(input, i+j);
       END;
       Transform(md5ctx.state, locbuff);
       INC(i, 64);
     END;
     index := 0;
   ELSE
     i := 0;
   END;
   j := 0;
   WHILE i+j < Text.Length(input) DO
     md5ctx.buffer[j+index] := Text.GetChar(input, i+j);
     INC(j);
   END;
 END Update;

PROCEDURE Final(VAR md5ctx: T): Digest=

 VAR bits: ARRAY [0..7] OF CHAR;
     index, padLen: INTEGER;
     digest: Digest;
 PROCEDURE Encode(VAR output: ARRAY OF CHAR;
                  VAR input: ARRAY OF Word.T;
                  count: INTEGER) =
   BEGIN
     FOR i := 0 TO count DO
       output[i*4+0] := VAL(Word.Extract(input[i],  0, 8), CHAR);
       output[i*4+1] := VAL(Word.Extract(input[i],  8, 8), CHAR);
       output[i*4+2] := VAL(Word.Extract(input[i], 16, 8), CHAR);
       output[i*4+3] := VAL(Word.Extract(input[i], 24, 8), CHAR)
     END;
   END Encode; 
 BEGIN
   Encode(bits, md5ctx.count, 1);
   index := Word.And(Word.Shift(md5ctx.count[0], -3), 16_3F);
   IF index < 56 THEN
     padLen := 56 - index;
   ELSE
     padLen := 120 - index;
   END;
   Update(md5ctx, Text.Sub(padding, 0, padLen));
   Update(md5ctx, Text.FromChars(bits));
   Encode(digest, md5ctx.state, 3);
   RETURN digest;
 END Final;

PROCEDURE ToText(hash: Digest): TEXT =

 VAR buf: TEXT := "";
 BEGIN
   FOR i := 0 TO 15 DO
     buf := buf & Fmt.Pad(Fmt.Int(ORD(hash[i]), 16), 2, '0');
   END;
   RETURN buf;
 END ToText;

BEGIN END MD5.</lang> Example usage: <lang modula3>MODULE Main;

IMPORT MD5, IO;

VAR md5ctx: MD5.T;

BEGIN

 MD5.Init(md5ctx);
 MD5.Update(md5ctx, "The quick brown fox jumped over the lazy dog's back");
 IO.Put(MD5.ToText(MD5.Final(md5ctx)) & "\n");

END Main.</lang> Output:

e38ca1d920c4b8b8d3946b2c72f01680

MOO

<lang moo>string = "The quick brown fox jumped over the lazy dog's back"; player:tell(string_hash(string));</lang>

Objective-C

Works with: GNUstep

only; not Cocoa

<lang objc>NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; NSData *digest = [[myString dataUsingEncoding:NSUTF8StringEncoding] md5Digest]; // or another encoding of your choosing NSLog(@"%@", [digest hexadecimalRepresentation]);</lang>

Works with: Mac OS X

(not yet tested)

<lang objc>#include <openssl/md5.h>

NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; NSData *data = [myString dataUsingEncoding:NSUTF8StringEncoding]; // or another encoding of your choosing unsigned char digest[MD5_DIGEST_LENGTH]; if (MD5([data bytes], [data length], digest)) {

   NSMutableString *hex = [NSMutableString string];
   for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
       [hex appendFormat: @"%02x", (int)(digest[i])];
   }
   NSLog(@"%@", hex);

}</lang>

Works with: iPhone

(not yet tested)

<lang objc>#import <CommonCrypto/CommonDigest.h>

NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; NSData *data = [myString dataUsingEncoding:NSUTF8StringEncoding]; // or another encoding of your choosing unsigned char digest[CC_MD5_DIGEST_LENGTH]; if (CC_MD5([data bytes], [data length], digest)) {

   NSMutableString *hex = [NSMutableString string];
   for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
       [hex appendFormat: @"%02x", (int)(digest[i])];
   }
   NSLog(@"%@", hex);

}</lang>

OCaml

<lang ocaml># Digest.to_hex(Digest.string "The quick brown fox jumped over the lazy dog's back") ;; - : string = "e38ca1d920c4b8b8d3946b2c72f01680"</lang>

Octave

<lang octave>s = "The quick brown fox jumped over the lazy dog's back"; hash = md5sum(s, true); disp(hash)</lang>

Perl

<lang perl>use Digest::MD5 qw(md5_hex);

print md5_hex("The quick brown fox jumped over the lazy dog's back"), "\n";</lang>

The same in OO manner <lang perl>use Digest::MD5;

$md5 = Digest::MD5->new; $md5->add("The quick brown fox jumped over the lazy dog's back"); print $md5->hexdigest, "\n";</lang>

PHP

<lang php>$string = "The quick brown fox jumped over the lazy dog's back"; echo md5( $string );</lang>

Pike

<lang pike>import String; import Crypto.MD5;

int main(){

  write( string2hex( hash( "The quick brown fox jumped over the lazy dog's back" ) ) + "\n" );

}</lang>

PowerShell

Translation of: C#

<lang powershell>$string = "The quick brown fox jumped over the lazy dog's back" $data = [Text.Encoding]::UTF8.GetBytes($string) $hash = [Security.Cryptography.MD5]::Create().ComputeHash($data) ([BitConverter]::ToString($hash) -replace '-').ToLower()</lang>

Python

Using builtin libraries:

Python 2.5 and later: <lang python>>>> import hashlib >>> print hashlib.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() e38ca1d920c4b8b8d3946b2c72f01680</lang>

Pre-2.5; removed in 3.x: <lang python>>>> import md5 >>> print md5.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() e38ca1d920c4b8b8d3946b2c72f01680</lang>

R

<lang R>library(digest) hexdigest <- digest("The quick brown fox jumped over the lazy dog's back",

                   algo="md5", serialize=FALSE)</lang>

REBOL

<lang rebol> >> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 == #{08A008A01D498C404B0C30852B39D3B8}</lang>

Ruby

<lang ruby>require 'digest/md5' Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back")

  1. => "e38ca1d920c4b8b8d3946b2c72f01680"</lang>

Slate

You must load the code in 'src/lib/md5.slate'. <lang slate> 'The quick brown fox jumped over the lazy dog\'s back' md5String. "==> 'e38ca1d920c4b8b8d3946b2c72f01680'" </lang>

Smalltalk

Works with: GNU Smalltalk

<lang smalltalk>PackageLoader fileInPackage: 'Digest' ! (MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dogs back') displayNl.</lang>

SQL

Works with: MySQL

<lang sql>SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')</lang>

Tcl

This md5 package is part of

Library: tcllib

which is bundled with most Tcl distributions.

<lang tcl>package require md5 puts [md5::md5 -hex "The quick brown fox jumped over the lazy dog's back"]

  1. ==> E38CA1D920C4B8B8D3946B2C72F01680</lang>

UNIX Shell

UNIX Shells are typically scripting languages, so they execute system commands. (Such as md5, in this case.)

<lang bash>echo "The quick brown fox jumped over the lazy dog's back"|md5</lang>