MD5
Encode a string using an MD5 algorithm. The algorithm can be found on the wiki.
You are encouraged to solve this task according to the task description, using any language you may know.
Ada
<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
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- 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>
- include <stdio.h>
- include <string.h>
- 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
<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
(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
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>
(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>
(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
<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")
- => "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
<lang smalltalk>PackageLoader fileInPackage: 'Digest' ! (MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dogs back') displayNl.</lang>
SQL
<lang sql>SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')</lang>
Tcl
This md5 package is part of
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"]
- ==> 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>