MD5: Difference between revisions
Gregg.irwin (talk | contribs) Added REBOL solution |
Gregg.irwin (talk | contribs) |
||
Line 854: | Line 854: | ||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
<lang rebol> |
<lang rebol> |
||
>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 |
>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 |
||
== #{08A008A01D498C404B0C30852B39D3B8}</lang> |
== #{08A008A01D498C404B0C30852B39D3B8}</lang> |
Revision as of 20:15, 17 February 2010
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
<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" clone 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>