MD5: Difference between revisions
m (added whitespace to the task's preamble; a minor word change.) |
|||
Line 2: | Line 2: | ||
;Task: |
;Task: |
||
Encode a string using an MD5 algorithm. The algorithm can be found on [[wp:Md5#Algorithm| |
Encode a string using an MD5 algorithm. The algorithm can be found on [[wp:Md5#Algorithm|Wikipedia]]. |
||
Optionally, validate your implementation by running all of the test values in [http://tools.ietf.org/html/rfc1321 IETF RFC (1321) for MD5]. |
Optionally, validate your implementation by running all of the test values in [http://tools.ietf.org/html/rfc1321 IETF RFC (1321) for MD5]. Additionally, the RFC provides more precise information on the algorithm than the Wikipedia article. |
||
{{alertbox|lightgray|'''Warning:''' MD5 has [http://tools.ietf.org/html/rfc6151 known weaknesses], including '''collisions''' and [http://www.win.tue.nl/hashclash/rogue-ca/ forged signatures]. Users may consider a stronger alternative when doing production-grade cryptography, such as SHA-256 (from the SHA-2 family) or the upcoming SHA-3.}} |
{{alertbox|lightgray|'''Warning:''' MD5 has [http://tools.ietf.org/html/rfc6151 known weaknesses], including '''collisions''' and [http://www.win.tue.nl/hashclash/rogue-ca/ forged signatures]. Users may consider a stronger alternative when doing production-grade cryptography, such as SHA-256 (from the SHA-2 family), or the upcoming SHA-3.}} |
||
If the solution on this page is a library solution, see [[MD5/Implementation]] for an implementation from scratch. |
If the solution on this page is a library solution, see [[MD5/Implementation]] for an implementation from scratch. |
||
<br><br> |
<br><br> |
||
Revision as of 18:46, 1 July 2016
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Encode a string using an MD5 algorithm. The algorithm can be found on Wikipedia.
Optionally, validate your implementation by running all of the test values in IETF RFC (1321) for MD5. Additionally, the RFC provides more precise information on the algorithm than the Wikipedia article.
If the solution on this page is a library solution, see MD5/Implementation for an implementation from scratch.
8th
<lang forth> "md5" cr:hash! "Some text" cr:hash cr:hash>s . cr bye </lang>
- Output:
9db5682a4d778ca2cb79580bdb67083f
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>
ALGOL 68
<lang algol68>
- Based on wikipedia article pseudocode #
- s specifies the per-round shift amounts #
[]INT s = (7,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);
[]BITS k = (16rd76aa478, 16re8c7b756, 16r242070db, 16rc1bdceee, 16rf57c0faf, 16r4787c62a, 16ra8304613, 16rfd469501, 16r698098d8, 16r8b44f7af, 16rffff5bb1, 16r895cd7be, 16r6b901122, 16rfd987193, 16ra679438e, 16r49b40821, 16rf61e2562, 16rc040b340, 16r265e5a51, 16re9b6c7aa, 16rd62f105d, 16r02441453, 16rd8a1e681, 16re7d3fbc8, 16r21e1cde6, 16rc33707d6, 16rf4d50d87, 16r455a14ed, 16ra9e3e905, 16rfcefa3f8, 16r676f02d9, 16r8d2a4c8a, 16rfffa3942, 16r8771f681, 16r6d9d6122, 16rfde5380c, 16ra4beea44, 16r4bdecfa9, 16rf6bb4b60, 16rbebfbc70, 16r289b7ec6, 16reaa127fa, 16rd4ef3085, 16r04881d05, 16rd9d4d039, 16re6db99e5, 16r1fa27cf8, 16rc4ac5665, 16rf4292244, 16r432aff97, 16rab9423a7, 16rfc93a039, 16r655b59c3, 16r8f0ccc92, 16rffeff47d, 16r85845dd1, 16r6fa87e4f, 16rfe2ce6e0, 16ra3014314, 16r4e0811a1, 16rf7537e82, 16rbd3af235, 16r2ad7d2bb, 16reb86d391);
OP + = (BITS a, b) BITS:
BEGIN BITS c = BIN (ABS (a AND 16rffff) + ABS (b AND 16rffff)); BITS d = BIN (ABS (a SHR 16) + ABS (b SHR 16) + ABS (c SHR 16)); (c AND 16rffff) OR (d SHL 16) END;
- [0:63]LONG INT k;
FOR i FROM 0 TO 63 DO
k[i] := ENTIER (ABS (sin(i+1)) * LONG INT(2)**32)
OD;#
PROC md5 = (STRING intext) STRING:
BEGIN # Initialize variables: # BITS a0 := 16r67452301, a1 := 16refcdab89, a2 := 16r98badcfe, a3 := 16r10325476;
STRING text := intext; # Pre-processing: adding a single 1 bit # text +:= REPR 128; # Pre-processing: padding with zeros append "0" bit until message length in bits ≡ 448 (mod 512) # WHILE ELEMS text MOD 64 ≠ 56 DO text +:= REPR 0 OD; # append original length in bits mod (2 pow 64) to message # text +:= dec2asc (ELEMS intext * 8); # MD5 rounds # # Process the message in successive 512-bit chunks: # WHILE text ≠ "" DO
# for each 512-bit (64 byte) chunk of message # []CHAR chunk = text[1:64]; text := text[65:]; # break chunk into sixteen 32-bit words M[j], 0 <= j <= 15 # [0:15]BITS m;
FOR j FROM 0 TO 15 DO m[j] := BIN (ABS chunk[j*4+1]) OR
BIN (ABS chunk[j*4+2]) SHL 8 OR BIN (ABS chunk[j*4+3]) SHL 16 OR BIN (ABS chunk[j*4+4]) SHL 24
OD; INT g;
BITS a, b, c, d, f, dtemp;
# Initialize hash value for this chunk # a := a0;
b := a1; c := a2; d := a3; FOR i FROM 0 TO 63 DO IF 0 <= i AND i <= 15 THEN
f := (b AND c) OR ((NOT b) AND d); g := i ELIF 16 <= i AND i <= 31 THEN f := (d AND b) OR ((NOT d) AND c); g := (5×i + 1) MOD 16 ELIF 32 <= i AND i <= 47 THEN f := b XOR c XOR d; g := (3×i + 5) MOD 16 ELIF 48 <= i AND i <= 63 THEN f := c XOR (b OR (NOT d)); g := (7×i) MOD 16 FI; dtemp := d; d := c; c := b; b := b + leftrotate ((a + f + k[1+i] + m[g]), s[1+i]); a := dtemp
OD;
# Add this chunk's hash to result so far #
a0 := a0 + a; a1 := a1 + b; a2 := a2 + c; a3 := a3 + d OD; revhex (a0) + revhex (a1) + revhex (a2) + revhex (a3) END;
PROC leftrotate = (BITS x, INT c) BITS:
(x SHL c) OR (x SHR (32-c));
- dec2asc: dec to 8 byte asc #
PROC dec2asc = (INT nn)STRING:
BEGIN STRING h := ""; INT n := nn; FOR i TO 8 DO h +:= REPR (n MOD 256); n ÷:= 256 OD; h END;
PROC revhex = (BITS x) STRING : BEGIN # Convert to lowercase hexadecimal STRING # PROC hexdig = (BITS x) CHAR: (REPR (ABS(x) <= 9 | ABS(x) + ABS("0") | ABS(x) - 10 + ABS("a"))); hexdig (x SHR 4 AND 16rf) + hexdig (x AND 16rf) + hexdig (x SHR 12 AND 16rf) + hexdig (x SHR 8 AND 16rf) + hexdig (x SHR 20 AND 16rf) + hexdig (x SHR 16 AND 16rf) + hexdig (x SHR 28 AND 16rf) + hexdig (x SHR 24 AND 16rf) END;
STRING testmsg = "The quick brown fox jumps over the lazy dog"; STRING checksum = "9e107d9d372bb6826bd81d3542a419d6";
print ((testmsg, new line)); print ((checksum, new line));
STRING test = md5 (testmsg);
IF test = checksum THEN
print (("passed", new line)); print ((test, new line))
ELSE
print (("failed"))
FI </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>
BBC BASIC
See MD5/Implementation for a native version. <lang bbcbasic> PRINT FN_MD5("")
PRINT FN_MD5("a") PRINT FN_MD5("abc") PRINT FN_MD5("message digest") PRINT FN_MD5("abcdefghijklmnopqrstuvwxyz") PRINT FN_MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") PRINT FN_MD5(STRING$(8,"1234567890")) END DEF FN_MD5(message$) LOCAL I%, MD5$, MD5_CTX{} DIM MD5_CTX{i%(1), buf%(3), in&(63), digest&(15)} SYS "MD5Init", MD5_CTX{} SYS "MD5Update", MD5_CTX{}, message$, LEN(message$) SYS "MD5Final", MD5_CTX{} FOR I% = 0 TO 15 MD5$ += RIGHT$("0"+STR$~(MD5_CTX.digest&(I%)),2) NEXT = MD5$</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 (Needs review - differences observed for the last 8 characters when compared with openssl implementation) <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+8)/64; msg2 = 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; }
if( msg2 ) free( msg2 );
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 cpp>#include <string>
- include <iostream>
- include "Poco/MD5Engine.h"
- include "Poco/DigestStream.h"
using Poco::DigestEngine ; using Poco::MD5Engine ; using Poco::DigestOutputStream ;
int main( ) {
std::string myphrase ( "The quick brown fox jumped over the lazy dog's back" ) ; MD5Engine md5 ; DigestOutputStream outstr( md5 ) ; outstr << myphrase ; outstr.flush( ) ; //to pass everything to the digest engine const DigestEngine::Digest& digest = md5.digest( ) ; std::cout << myphrase << " as a MD5 digest :\n" << DigestEngine::digestToHex( digest ) << " !" << std::endl ; return 0 ;
}</lang>
- Output:
The quick brown fox jumped over the lazy dog's back as a MD5 digest : e38ca1d920c4b8b8d3946b2c72f01680 !
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>
Caché ObjectScript
USER>set hash=$System.Encryption.MD5Hash("The quick brown fox jumped over the lazy dog's back") USER>zzdump hash 0000: E3 8C A1 D9 20 C4 B8 B8 D3 94 6B 2C 72 F0 16 80
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
<lang lisp>(ql:quickload 'ironclad) (defun md5 (str)
(ironclad:byte-array-to-hex-string (ironclad:digest-sequence :md5 (ironclad:ascii-string-to-byte-array str))))
(defvar *tests* '(""
"a" "abc" "message digest" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" "12345678901234567890123456789012345678901234567890123456789012345678901234567890"))
(dolist (msg *tests*)
(format T "~s: ~a~%" msg (md5 msg)))
</lang>
- Output:
"": d41d8cd98f00b204e9800998ecf8427e "a": 0cc175b9c0f1b6a831c399e269772661 "abc": 900150983cd24fb0d6963f7d28e17f72 "message digest": f96b697d7cb7938d525a2f31aaf161d0 "abcdefghijklmnopqrstuvwxyz": c3fcd3d76192e4007dfb496cca67e13b "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": d174ab98d277d9f5a5611c2c9f419d9f "12345678901234567890123456789012345678901234567890123456789012345678901234567890": 57edf4a22be3c955ac49da2e2107b67a
Another method using openssl:
<lang lisp>(cffi:load-foreign-library "libcrypto.so")
(cffi:defcfun ("MD5" MD5) :void (string :string) (len :int) (ptr :pointer))
(let ((string-to-convert "The quick brown fox jumped over the lazy dog's back")
(ptr (cffi:foreign-alloc :unsigned-char :count 16))) (md5 string-to-convert (length string-to-convert) ptr) (loop for i from 0 below 16 do (format t "~a" (write-to-string (cffi:mem-ref ptr :unsigned-char i) :base 16))) (cffi:foreign-free ptr))</lang>
- Output:
E38CA1D920C4B8B8D3946B2C72F01680
D
<lang d>void main() {
import std.stdio, std.digest.md;
auto txt = "The quick brown fox jumped over the lazy dog's back"; writefln("%-(%02x%)", txt.md5Of);
}</lang>
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Alternative version:
<lang d>import tango.io.digest.Md5, 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> 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]
Delphi
If you require a native implementation, look inside the class TIdHashMessageDigest5. This class is placed in the unit IdHashMessageDigest.pas. <lang Delphi>program MD5Hash;
{$APPTYPE CONSOLE}
uses
SysUtils, IdHashMessageDigest;
function MD5(aValue: string): string; begin
with TIdHashMessageDigest5.Create do begin Result:= HashStringAsHex(aValue); Free; end;
end;
begin
Writeln(MD5()); Writeln(MD5('a')); Writeln(MD5('abc')); Writeln(MD5('message digest')); Writeln(MD5('abcdefghijklmnopqrstuvwxyz')); Writeln(MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')); Writeln(MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890')); Readln;
end.</lang> Output:
D41D8CD98F00B204E9800998ECF8427E 0CC175B9C0F1B6A831C399E269772661 900150983CD24FB0D6963F7D28E17F72 F96B697D7CB7938D525A2F31AAF161D0 C3FCD3D76192E4007DFB496CCA67E13B D174AB98D277D9F5A5611C2C9F419D9F 57EDF4A22BE3C955AC49DA2E2107B67A
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>
Emacs Lisp
Emacs 23 and up includes md5
giving the MD5 hash as a hexadecimal string. (See GNU Elisp manual on Checksum/Hash).
<lang Lisp>(md5 "The quick brown fox jumped over the lazy dog's back") => "e38ca1d920c4b8b8d3946b2c72f01680"</lang>
This began in FLIM and FLIM has an md5.el
which creates an md5
func if it doesn't already exist.
hmac-md5.el
also from FLIM and also included in recent Emacs has an md5-binary
giving the checksum as 16 binary bytes. encode-hex-string
from hex-util.el
can convert that to hex the same as the md5
func gives.
<lang Lisp>(require 'hmac-md5) (require 'hex-util) (encode-hex-string
(md5-binary "The quick brown fox jumped over the lazy dog's back"))
=> "e38ca1d920c4b8b8d3946b2c72f01680"</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
<lang 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</lang>
Frink
The function messageDigest[string, hash]
returns a hex-encoded hash of any input string with a variety of hashing functions.
<lang frink>println[messageDigest["The quick brown fox", "MD5"]]</lang>
Go
<lang go>package main
import (
"crypto/md5" "fmt"
)
func main() {
for _, p := range [][2]string{ // RFC 1321 test cases {"d41d8cd98f00b204e9800998ecf8427e", ""}, {"0cc175b9c0f1b6a831c399e269772661", "a"}, {"900150983cd24fb0d6963f7d28e17f72", "abc"}, {"f96b697d7cb7938d525a2f31aaf161d0", "message digest"}, {"c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"}, {"d174ab98d277d9f5a5611c2c9f419d9f", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, {"57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890" + "123456789012345678901234567890123456789012345678901234567890"}, // test case popular with other RC solutions {"e38ca1d920c4b8b8d3946b2c72f01680", "The quick brown fox jumped over the lazy dog's back"}, } { validate(p[0], p[1]) }
}
var h = md5.New()
func validate(check, s string) {
h.Reset() h.Write([]byte(s)) sum := fmt.Sprintf("%x", h.Sum(nil)) if sum != check { fmt.Println("MD5 fail") fmt.Println(" for string,", s) fmt.Println(" expected: ", check) fmt.Println(" got: ", sum) }
}</lang>
Groovy
<lang Groovy>import java.security.MessageDigest
String.metaClass.md5Checksum = {
MessageDigest.getInstance('md5').digest(delegate.bytes).collect { String.format("%02x", it) }.join()
}</lang> Testing <lang Groovy>assert 'The quick brown fox jumps over the lazy dog'.md5Checksum() == '9e107d9d372bb6826bd81d3542a419d6'</lang>
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
let message = "The quick brown fox jumped over the lazy dog's back" digest = (md5sum . pack . map (fromIntegral . ord)) message putStrLn digest</lang>
Use in GHCi:
*Main> main e38ca1d920c4b8b8d3946b2c72f01680
This version uses the Cryptonite package:
<lang haskell>#!/usr/bin/env runhaskell
import Data.ByteString.Char8 (pack) import System.Environment (getArgs) import Crypto.Hash
main :: IO () main = print . md5 . pack . unwords =<< getArgs
where md5 x = hash x :: Digest MD5</lang>
- Output:
$ ./md5.hs The quick brown fox jumped over the lazy dog\'s back e38ca1d920c4b8b8d3946b2c72f01680
Io
<lang io>Io> MD5 ==> MD5_0x97663e0:
appendSeq = MD5_appendSeq() md5 = MD5_md5() md5String = MD5_md5String()
Io> MD5 clone appendSeq("The quick brown fox jumped over the lazy dog's back") md5String ==> e38ca1d920c4b8b8d3946b2c72f01680</lang>
Icon and Unicon
The following program demonstrates the MD5 using a native Icon/Unicon implementation (see MD5/Implementation) and checks the results against reference values. Alternate implementations using call outs to md5sum on Linux or fciv on windows are possible but were not coded. <lang Icon>procedure main() # validate against the RFC test strings and more
testMD5("The quick brown fox jumps over the lazy dog", 16r9e107d9d372bb6826bd81d3542a419d6) testMD5("The quick brown fox jumps over the lazy dog.", 16re4d909c290d0fb1ca068ffaddf22cbd0) testMD5("", 16rd41d8cd98f00b204e9800998ecf8427e)
end
procedure testMD5(s,rh) # compute the MD5 hash and compare it to reference value
write("Message(length=",*s,") = ",image(s)) write("Digest = ",hexstring(h := MD5(s)),if h = rh then " matches reference hash" else (" does not match reference hash = " || hexstring(rh)),"\n")
end</lang>
Sample Output:
Message(length=43) = "The quick brown fox jumps over the lazy dog" Digest = 9E107D9D372BB6826BD81D3542A419D6 matches reference hash Message(length=44) = "The quick brown fox jumps over the lazy dog." Digest = E4D909C290D0FB1CA068FFADDF22CBD0 matches reference hash Message(length=0) = "" Digest = D41D8CD98F00B204E9800998ECF8427E matches reference hash
J
Using the md5.ijs 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>
Since this md5.ijs script is no longer findable with a web search, it's included below:
<lang j>NB. convert/misc/md5 NB. RSA Data Security, Inc. MD5 Message-Digest Algorithm NB. version: 1.0.2 NB. NB. See RFC 1321 for license details NB. J implementation -- (C) 2003 Oleg Kobchenko; NB. NB. 09/04/2003 Oleg Kobchenko NB. 03/31/2007 Oleg Kobchenko j601, JAL NB. 12/17/2015 G.Pruss 64-bit NB. ~60+ times slower than using the jqt library
require 'convert' coclass 'pcrypt'
NB. lt= (*. -.)~ gt= *. -. ge= +. -. xor= ~: '`lt gt ge xor'=: (20 b.)`(18 b.)`(27 b.)`(22 b.) '`and or sh'=: (17 b.)`(23 b.)`(33 b.)
3 : 0 if. IF64 do. rot=: (16bffffffff and sh or ] sh~ 32 -~ [) NB. (y << x) | (y >>> (32 - x)) add=: ((16bffffffff&and)@+)"0 else. rot=: (32 b.) add=: (+&(_16&sh) (16&sh@(+ _16&sh) or and&65535@]) +&(and&65535))"0 end. EMPTY )
hexlist=: tolower@:,@:hfd@:,@:(|."1)@(256 256 256 256&#:)
cmn=: 4 : 0 'x s t'=. x [ 'q a b'=. y b add s rot (a add q) add (x add t) )
ff=: cmn (((1&{ and 2&{) or 1&{ lt 3&{) , 2&{.) gg=: cmn (((1&{ and 3&{) or 2&{ gt 3&{) , 2&{.) hh=: cmn (((1&{ xor 2&{)xor 3&{ ) , 2&{.) ii=: cmn (( 2&{ xor 1&{ ge 3&{ ) , 2&{.) op=: ff`gg`hh`ii
I=: ".;._2(0 : 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 6 11 0 5 10 15 4 9 14 3 8 13 2 7 12 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9 ) S=: 4 4$7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21
T=: |:".;._2(0 : 0)
_680876936 _165796510 _378558 _198630844 _389564586 _1069501632 _2022574463 1126891415 606105819 643717713 1839030562 _1416354905
_1044525330 _373897302 _35309556 _57434055
_176418897 _701558691 _1530992060 1700485571 1200080426 38016083 1272893353 _1894986606
_1473231341 _660478335 _155497632 _1051523
_45705983 _405537848 _1094730640 _2054922799 1770035416 568446438 681279174 1873313359
_1958414417 _1019803690 _358537222 _30611744
_42063 _187363961 _722521979 _1560198380
_1990404162 1163531501 76029189 1309151649
1804603682 _1444681467 _640364487 _145523070 _40341101 _51403784 _421815835 _1120210379
_1502002290 1735328473 530742520 718787259
1236535329 _1926607734 _995338651 _343485551
)
norm=: 3 : 0 n=. 16 * 1 + _6 sh 8 + #y b=. n#0 [ y=. a.i.y for_i. i. #y do.
b=. ((j { b) or (8*4|i) sh i{y) (j=. _2 sh i) } b
end. b=. ((j { b) or (8*4|i) sh 128) (j=._2 sh i=.#y) } b _16]\ (8 * #y) (n-2) } b )
NB.*md5 v MD5 Message-Digest Algorithm NB. diagest=. md5 message md5=: 3 : 0 X=. norm y q=. r=. 1732584193 _271733879 _1732584194 271733878 for_x. X do.
for_j. i.4 do. l=. ((j{I){x) ,. (16$j{S) ,. j{T for_i. i.16 do. r=. _1|.((i{l) (op@.j) r),}.r end. end. q=. r=. r add q
end. hexlist r )
md5_z_=: md5_pcrypt_
Note 'tests suite'
(>,. '='"_,. md5&>@]) ;'a';'abc';'message digest' =d41d8cd98f00b204e9800998ecf8427e
a =0cc175b9c0f1b6a831c399e269772661 abc =900150983cd24fb0d6963f7d28e17f72 message digest=f96b697d7cb7938d525a2f31aaf161d0
(,: md5) (i.26)&+&.(a.&i.)'a'
abcdefghijklmnopqrstuvwxyz c3fcd3d76192e4007dfb496cca67e13b
(,: md5) a.{~(a.i.'Aa0');@:(<@(+i.)"0) 26 26 10
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 d174ab98d277d9f5a5611c2c9f419d9f
(,: md5) 80$'1234567890'
12345678901234567890123456789012345678901234567890123456789012345678901234567890 57edf4a22be3c955ac49da2e2107b67a ) </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.
Julia
<lang Julia> using Nettle
function md5sum(s::String)
bytes2hex(md5_hash(s))
end
function Base.trunc(s::String, n::Integer)
0 < n || throw(DomainError()) len = length(s) len > n || return s 3 < n || return s[1:n] return s[1:n-3]*"..."
end
tests = ["" => "d41d8cd98f00b204e9800998ecf8427e",
"a" => "0cc175b9c0f1b6a831c399e269772661", "abc" => "900150983cd24fb0d6963f7d28e17f72", "message digest" => "f96b697d7cb7938d525a2f31aaf161d0", "abcdefghijklmnopqrstuvwxyz" => "c3fcd3d76192e4007dfb496cca67e13b", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" => "d174ab98d277d9f5a5611c2c9f419d9f", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" => "57edf4a22be3c955ac49da2e2107b67a", "foobad" => "3858f62230ac3c915f300c664312c63f"]
println("Testing Julia's MD5 hash against RFC 1321.")
for k in sort(collect(keys(tests)), by=(x)->length(x))
mysum = md5sum(k) print(@sprintf(" %15s => ", trunc(k, 15)), mysum) if mysum == tests[k] println(" MD5 OK") else println(" MD5 Bad") println(" The sum should be ", tests[k]) end
end </lang> trunc is a Julia built-in for numbers, that this program extends it to strings.
- Output:
Testing is done using the test suite specified in the RFC. I added "foobad" with a bogus hash (that of "foobar") to demonstrate that the test identifies bad hashes.
Testing Julia's MD5 hash against RFC 1321. => d41d8cd98f00b204e9800998ecf8427e MD5 OK a => 0cc175b9c0f1b6a831c399e269772661 MD5 OK abc => 900150983cd24fb0d6963f7d28e17f72 MD5 OK foobad => 6ce0d31e08fc3c4de8e3b2fa0d3d72ff MD5 Bad The sum should be 3858f62230ac3c915f300c664312c63f message digest => f96b697d7cb7938d525a2f31aaf161d0 MD5 OK abcdefghijkl... => c3fcd3d76192e4007dfb496cca67e13b MD5 OK ABCDEFGHIJKL... => d174ab98d277d9f5a5611c2c9f419d9f MD5 OK 123456789012... => 57edf4a22be3c955ac49da2e2107b67a MD5 OK
Lasso
<lang Lasso>Encrypt_MD5('Welcome all Rhinos!') //80ba88ee2600e9e9b36e739458c39ebd</lang>
Test suite
<lang Lasso>local(test = map( 'a' = '0cc175b9c0f1b6a831c399e269772661', 'abc' = '900150983cd24fb0d6963f7d28e17f72', 'message digest' = 'f96b697d7cb7938d525a2f31aaf161d0', 'abcdefghijklmnopqrstuvwxyz' = 'c3fcd3d76192e4007dfb496cca67e13b', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' = 'd174ab98d277d9f5a5611c2c9f419d9f', '12345678901234567890123456789012345678901234567890123456789012345678901234567890' = '57edf4a22be3c955ac49da2e2107b67a' ) ) with a in #test->keys do => {^ 'testing: "'+#a+'": '+(Encrypt_MD5(#a)->asBytes == #test->find(#a)->asBytes)+'\r' ^}</lang>
- Output:
testing: "12345678901234567890123456789012345678901234567890123456789012345678901234567890": true testing: "a": true testing: "abc": true testing: "abcdefghijklmnopqrstuvwxyz": true testing: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": true testing: "message digest": true
Liberty BASIC
<lang lb>'[RC]MD5
'from tsh73's January 2008 code
text$="The quick brown fox jumps over the lazy dog" checkSum$="9e107d9d372bb6826bd81d3542a419d6"
print text$ print checkSum$
test$=md5$(text$)
if test$=checkSum$ then print "passed" print test$ else print "failed" end if end
function md5$(text$)
dim r(64) dim k(64) dim w(16) global two32 two32=2^32
'prepare the MD5 checksum table restore [perRoundShiftAmounts] for i=0 to 63 read x r(i)=x next
'prepare constants for i=0 to 63 k(i) = int(abs(sin(i+1)) * two32) next
'initialise variables h0 = HEXDEC("67452301") h1 = HEXDEC("EFCDAB89") h2 = HEXDEC("98BADCFE") h3 = HEXDEC("10325476")
'find num bits in message numbits=len(text$)*8
'add bits "10000000" text$=text$+chr$(128)
'add bits "00000000" while len(text$) mod 64 <> 56 text$=text$+chr$(0) wend
'add original length in bits text$=text$+dec2asc$(numbits)
'MD5 rounds 'process in 64 byte chunks 512bits for chunk = 1 to len(text$) step 64 chunk$ = mid$(text$, chunk, 64) for word = 0 TO 15 'invert byte order b0 = asc(mid$(chunk$, word*4+1, 1)) b1 = asc(mid$(chunk$, word*4+2, 1)) b2 = asc(mid$(chunk$, word*4+3, 1)) b3 = asc(mid$(chunk$, word*4+4, 1)) w(word) = ((b3*256+b2)*256+b1)*256+b0 next word a = h0 b = h1 c = h2 d = h3 for i = 0 to 63 select case case 0 <= i and i <= 15 f = (b and c) or (bitNot(b) and d) g = i case 16 <= i and i <= 31 f = (d and b) or (bitNot(d) and c) g = (5 * i + 1) mod 16 case 32 <= i and i <= 47 f = b xor c xor d g = (3 * i + 5) mod 16 case 48 <= i and i <= 63 f = c xor (b or bitNot(d)) g = (7 * i) mod 16 end select temp = d d = c c = b b=b+leftrotate(a + f + k(i) + w(g),r(i)) b = b mod two32 a = temp next i h0 = (h0 + a) mod two32 h1 = (h1 + b) mod two32 h2 = (h2 + c) mod two32 h3 = (h3 + d) mod two32 next chunk
md5$ = revOrd$(DECHEX$(h0))+_ revOrd$(DECHEX$(h1))+_ revOrd$(DECHEX$(h2))+_ revOrd$(DECHEX$(h3))
[perRoundShiftAmounts] DATA 7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22 DATA 5, 9,14,20, 5, 9,14,20, 5, 9,14,20, 5, 9,14,20 DATA 4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23 DATA 6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21
end function
' dec2asc: dec to 8 byte asc function dec2asc$(n) h$ = "" for i = 1 to 8 h$ = h$ + chr$(n mod 256) n = int(n/256) next dec2asc$= h$ end function
' bitNot function bitNot(num) bitNot = two32 -1 -num end function
' leftrotate: spins bits left n times function leftrotate(num,times) num=num mod two32 r = (num*2^times) mod two32 l = int(num/(2^(32-times))) leftrotate = r+l end function
' reverse the HEXDEC$ order function revOrd$(a$) a$=left$("00000000", 8-len(a$))+a$ revOrd$ = lower$(mid$(a$,7,2)+mid$(a$,5,2)+mid$(a$,3,2)+mid$(a$,1,2)) end function</lang>
LiveCode
Livecode has built-in support for md4 and md5 <lang LiveCode>function md5sum hashtext
local md5, mdhex put md5Digest(hashtext) into md5 get binaryDecode("H*",md5,mdhex) return mdhex
end md5sum</lang>
Tests<lang LiveCode>command md5testsuite
// rfc1321 MD5 test suite: local md5 put md5sum("") is "d41d8cd98f00b204e9800998ecf8427e" into md5["empty"] put md5sum("a") is "0cc175b9c0f1b6a831c399e269772661" into md5["a"] put md5sum("abc") is "900150983cd24fb0d6963f7d28e17f72" into md5["abc"] put md5sum("message digest") is "f96b697d7cb7938d525a2f31aaf161d0" into md5["message digest"] put md5sum("abcdefghijklmnopqrstuvwxyz") is "c3fcd3d76192e4007dfb496cca67e13b" \ into md5["abclower"] put md5sum("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") \ is "d174ab98d277d9f5a5611c2c9f419d9f" into md5["abcupper"] put md5sum("12345678901234567890123456789012345678901234567890123456789012345678901234567890")\ is "57edf4a22be3c955ac49da2e2107b67a" into md5["123"] repeat for each line n in the keys of md5 if md5[n] is not true then put "err" & tab & n & return after results exit repeat else put "ok" & tab & n & return after results end if end repeat put results
end md5testsuite</lang> Output
ok abc ok abclower ok 123 ok abcupper ok message digest ok a ok empty
Lua
Using the Kepler MD5 library: <lang Lua>require "md5"
--printing a sum: print(md5.sumhexa"The quick brown fox jumps over the lazy dog")
--running the test suite:
local function test(msg,sum) assert(md5.sumhexa(msg)==sum) end
test("","d41d8cd98f00b204e9800998ecf8427e") test("a","0cc175b9c0f1b6a831c399e269772661") test("abc","900150983cd24fb0d6963f7d28e17f72") test("message digest","f96b697d7cb7938d525a2f31aaf161d0") test("abcdefghijklmnopqrstuvwxyz","c3fcd3d76192e4007dfb496cca67e13b") test("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789","d174ab98d277d9f5a5611c2c9f419d9f") test("12345678901234567890123456789012345678901234567890123456789012345678901234567890","57edf4a22be3c955ac49da2e2107b67a")</lang>
Maple
The Hash command in the StringTools package computes the MD5 hash value of a string. <lang Maple> > with( StringTools ): > Hash( "" );
"d41d8cd98f00b204e9800998ecf8427e"
> Hash( "a" );
"0cc175b9c0f1b6a831c399e269772661"
> Hash( "abc" );
"900150983cd24fb0d6963f7d28e17f72"
> Hash( "message digest" );
"f96b697d7cb7938d525a2f31aaf161d0"
> Hash( "abcdefghijklmnopqrstuvwxyz" );
"c3fcd3d76192e4007dfb496cca67e13b"
> Hash( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" );
"d174ab98d277d9f5a5611c2c9f419d9f"
> Hash( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" );
"57edf4a22be3c955ac49da2e2107b67a"
</lang>
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>
MATLAB
This code also works with Octave (but Octave already provides md5sum(), see Octave example).
<lang MATLAB>function digest = md5(message)
% digest = md5(message) % Compute the MD5 digest of the message, as a hexadecimal digest.
% Follow the MD5 algorithm from RFC 1321 [1] and Wikipedia [2]. % [1] http://tools.ietf.org/html/rfc1321 % [2] http://en.wikipedia.org/wiki/MD5
% m is the modulus for 32-bit unsigned arithmetic. m = 2 ^ 32;
% s is the shift table for circshift(). Each shift is negative % because it is a left shift. s = [-7, -12, -17, -22 -5, -9, -14, -20 -4, -11, -16, -23 -6, -10, -15, -21];
% t is the sine table. Each sine is a 32-bit integer, unsigned. t = floor(abs(sin(1:64)) .* m);
% Initialize the hash, as a row vector of 32-bit integers. digest = [hex2dec('67452301') ... hex2dec('EFCDAB89') ... hex2dec('98BADCFE') ... hex2dec('10325476')];
% If message contains characters, convert them to ASCII values. message = double(message); bytelen = numel(message);
% Pad the message by appending a 1, then appending enough 0s to make % the bit length congruent to 448 mod 512. Because we have bytes, we % append 128 '10000000', then append enough 0s '00000000's to make % the byte length congruent to 56 mod 64. message = [message, 128, zeros(1, mod(55 - bytelen, 64))];
% Convert the message to 32-bit integers, little endian. % For little endian, first byte is least significant byte. message = reshape(message, 4, numel(message) / 4); message = message(1,:) + ... % least significant byte message(2,:) * 256 + ... message(3,:) * 65536 + ... message(4,:) * 16777216; % most significant byte
% Append the bit length as a 64-bit integer, little endian. bitlen = bytelen * 8; message = [message, mod(bitlen, m), mod(bitlen / m, m)];
% Process each 512-bit block. Because we have 32-bit integers, each % block has 16 elements, message(k + (0:15)). for k = 1:16:numel(message) % Copy hash. a = digest(1); b = digest(2); c = digest(3); d = digest(4);
% Do 64 operations. for i = (1:64) % Convert b, c, d to row vectors of bits (0s and 1s). bv = dec2bin(b, 32) - '0'; cv = dec2bin(c, 32) - '0'; dv = dec2bin(d, 32) - '0';
% Find f = mix of b, c, d. % ki = index in 0:15, to message(k + ki). % sr = row in 1:4, to s(sr, :). if i <= 16 % Round 1 f = (bv & cv) | (~bv & dv); ki = i - 1; sr = 1; elseif i <= 32 % Round 2 f = (bv & dv) | (cv & ~dv); ki = mod(5 * i - 4, 16); sr = 2; elseif i <= 48 % Round 3 f = xor(bv, xor(cv, dv)); ki = mod(3 * i + 2, 16); sr = 3; else % Round 4 f = xor(cv, bv | ~dv); ki = mod(7 * i - 7, 16); sr = 4; end
% Convert f, from row vector of bits, to 32-bit integer. f = bin2dec(char(f + '0'));
% Do circular shift of sum. sc = mod(i - 1, 4) + 1; sum = mod(a + f + message(k + ki) + t(i), m); sum = dec2bin(sum, 32); sum = circshift(sum, [0, s(sr, sc)]); sum = bin2dec(sum);
% Update a, b, c, d. temp = d; d = c; c = b; b = mod(b + sum, m); a = temp; end %for i
% Add hash of this block to hash of previous blocks. digest = mod(digest + [a, b, c, d], m); end %for k
% Convert hash from 32-bit integers, little endian, to bytes. digest = [digest % least significant byte digest / 256 digest / 65536 digest / 16777216]; % most significant byte digest = reshape(mod(floor(digest), 256), 1, numel(digest));
% Convert hash to hexadecimal. digest = dec2hex(digest); digest = reshape(transpose(digest), 1, numel(digest));
end %md5</lang>
Sample Usage: <lang MATLAB>octave:14> md5('Rosetta Code') ans = CCA1BF66B09554E10F837838C3D3EFB1</lang>
MOO
<lang moo>string = "The quick brown fox jumped over the lazy dog's back"; player:tell(string_hash(string));</lang>
Nemerle
<lang Nemerle>using System; using System.Console; using System.Text; using System.Security.Cryptography; using Nemerle.Collections; using Nemerle.Collections.NCollectionsExtensions;
module Md5 {
HashMD5(input : string) : string { BitConverter.ToString (MD5.Create().ComputeHash(Encoding.Default.GetBytes(input))).Replace("-", "").ToLower() } IsValidMD5(text : string, hash : string) : bool { HashMD5(text) == hash.ToLower() } Main() : void { def examples = ["The quick brown fox jumped over the lazy dog's back", "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"]; def hashes = ["e38ca1d920c4b8b8d3946b2c72f01680", "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a"]; def tests = Hashtable(ZipLazy(examples, hashes)); foreach (test in tests) Write($"$(IsValidMD5(test.Key, test.Value)) "); }
}</lang> Output:
True True True True True True True True
NetRexx
<lang NetRexx>/* NetRexx */
options replace format comments java crossref savelog symbols binary
import java.security.MessageDigest
MD5('The quick brown fox jumps over the lazy dog', '9e107d9d372bb6826bd81d3542a419d6') -- RFC 1321 MD5 test suite: MD5("", 'd41d8cd98f00b204e9800998ecf8427e') MD5("a", '0cc175b9c0f1b6a831c399e269772661') MD5("abc", '900150983cd24fb0d6963f7d28e17f72') MD5("message digest", 'f96b697d7cb7938d525a2f31aaf161d0') MD5("abcdefghijklmnopqrstuvwxyz", 'c3fcd3d76192e4007dfb496cca67e13b') MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 'd174ab98d277d9f5a5611c2c9f419d9f') MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", '57edf4a22be3c955ac49da2e2107b67a')
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method MD5(messageText, verifyCheck) public static
algorithm = 'MD5' digestSum = getDigest(messageText, algorithm)
say '<Message>'messageText'</Message>' say Rexx('<'algorithm'>').right(12) || digestSum'</'algorithm'>' say Rexx('<Verify>').right(12) || verifyCheck'</Verify>' if digestSum == verifyCheck then say algorithm 'Confirmed' else say algorithm 'Failed'
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getDigest(messageText = Rexx, algorithm = Rexx 'MD5', encoding = Rexx 'UTF-8', lowercase = boolean 1) public static returns Rexx
algorithm = algorithm.upper encoding = encoding.upper
message = String(messageText) messageBytes = byte[] digestBytes = byte[] digestSum = Rexx
do messageBytes = message.getBytes(encoding) md = MessageDigest.getInstance(algorithm) md.update(messageBytes) digestBytes = md.digest
loop b_ = 0 to digestBytes.length - 1 bb = Rexx(digestBytes[b_]).d2x(2) if lowercase then digestSum = digestSum || bb.lower else digestSum = digestSum || bb.upper end b_ catch ex = Exception ex.printStackTrace end return digestSum
</lang> Output:
<Message>The quick brown fox jumps over the lazy dog</Message> <MD5>9e107d9d372bb6826bd81d3542a419d6</MD5> <Verify>9e107d9d372bb6826bd81d3542a419d6</Verify> MD5 Confirmed <Message></Message> <MD5>d41d8cd98f00b204e9800998ecf8427e</MD5> <Verify>d41d8cd98f00b204e9800998ecf8427e</Verify> MD5 Confirmed <Message>a</Message> <MD5>0cc175b9c0f1b6a831c399e269772661</MD5> <Verify>0cc175b9c0f1b6a831c399e269772661</Verify> MD5 Confirmed <Message>abc</Message> <MD5>900150983cd24fb0d6963f7d28e17f72</MD5> <Verify>900150983cd24fb0d6963f7d28e17f72</Verify> MD5 Confirmed <Message>message digest</Message> <MD5>f96b697d7cb7938d525a2f31aaf161d0</MD5> <Verify>f96b697d7cb7938d525a2f31aaf161d0</Verify> MD5 Confirmed <Message>abcdefghijklmnopqrstuvwxyz</Message> <MD5>c3fcd3d76192e4007dfb496cca67e13b</MD5> <Verify>c3fcd3d76192e4007dfb496cca67e13b</Verify> MD5 Confirmed <Message>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789</Message> <MD5>d174ab98d277d9f5a5611c2c9f419d9f</MD5> <Verify>d174ab98d277d9f5a5611c2c9f419d9f</Verify> MD5 Confirmed <Message>12345678901234567890123456789012345678901234567890123456789012345678901234567890</Message> <MD5>57edf4a22be3c955ac49da2e2107b67a</MD5> <Verify>57edf4a22be3c955ac49da2e2107b67a</Verify> MD5 Confirmed
NewLISP
<lang NewLISP>;; using the crypto module from http://www.newlisp.org/code/modules/crypto.lsp.html
- (import native functions from the crypto library, provided by OpenSSL)
(module "crypto.lsp") (crypto:md5 "The quick brown fox jumped over the lazy dog's back")</lang>
Nim
<lang nim>import md5
echo toMD5("The quick brown fox jumped over the lazy dog's back")</lang>
Oberon-2
<lang oberon2> MODULE MD5; IMPORT
Crypto:MD5, Crypto:Utils, Strings, Out;
VAR
h: MD5.Hash; str: ARRAY 128 OF CHAR;
BEGIN
h := MD5.NewHash(); h.Initialize; str := "The quick brown fox jumped over the lazy dog's back"; h.Update(str,0,Strings.Length(str)); h.GetHash(str,0); Out.String("MD5: ");Utils.PrintHex(str,0,h.size);Out.Ln
END MD5. </lang>
- Output:
MD5: E38CA1D9 20C4B8B8 D3946B2C 72F01680
Objeck
<lang objeck> class MD5 {
function : Main(args : String[]) ~ Nil { in := "The quick brown fox jumped over the lazy dog's back"->ToByteArray(); hash := Encryption.Hash->MD5(in); hash->ToHexString()->PrintLine(); }
} </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>
<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>
(need to include "libcrypto.dylib" framework)
<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>
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>
For an implementation of MD5, see MATLAB example.
OpenEdge/Progress
The MD5-DIGEST function is readily available, the output is passed thru HEX-ENCODE to convert the raw result to a hexadecimal string, this then needs to be passed thru STRING for display purposes. <lang progress>MESSAGE
1 STRING( HEX-ENCODE( MD5-DIGEST( "" ) ) ) SKIP 2 STRING( HEX-ENCODE( MD5-DIGEST( "a" ) ) ) SKIP 3 STRING( HEX-ENCODE( MD5-DIGEST( "abc" ) ) ) SKIP 4 STRING( HEX-ENCODE( MD5-DIGEST( "message digest" ) ) ) SKIP 5 STRING( HEX-ENCODE( MD5-DIGEST( "abcdefghijklmnopqrstuvwxyz" ) ) ) SKIP 6 STRING( HEX-ENCODE( MD5-DIGEST( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ) ) SKIP 7 STRING( HEX-ENCODE( MD5-DIGEST( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) ) )
VIEW-AS ALERT-BOX</lang>
Output:
--------------------------- Message --------------------------- 1 d41d8cd98f00b204e9800998ecf8427e 2 0cc175b9c0f1b6a831c399e269772661 3 900150983cd24fb0d6963f7d28e17f72 4 f96b697d7cb7938d525a2f31aaf161d0 5 c3fcd3d76192e4007dfb496cca67e13b 6 d174ab98d277d9f5a5611c2c9f419d9f 7 57edf4a22be3c955ac49da2e2107b67a --------------------------- OK ---------------------------
PARI/GP
Build a MD5 plugin using Linux system library and PARI's function interface. (Linux solution) <lang C>#include <pari/pari.h>
- include <openssl/md5.h>
- define HEX(x) (((x) < 10)? (x)+'0': (x)-10+'a')
/*
* PARI/GP func: MD5 hash * * gp code: install("plug_md5", "s", "MD5", "<library path>"); */
GEN plug_md5(char *text) {
char md[MD5_DIGEST_LENGTH]; char hash[sizeof(md) * 2 + 1]; int i;
MD5((unsigned char*)text, strlen(text), (unsigned char*)md);
for (i = 0; i < sizeof(md); i++) { hash[i+i] = HEX((md[i] >> 4) & 0x0f); hash[i+i+1] = HEX(md[i] & 0x0f); }
hash[sizeof(md) * 2] = 0;
return strtoGENstr(hash);
}</lang>
Compile with: gcc -Wall -O2 -fPIC -shared md5.c -o libmd5.so -lcrypt -lpari
Load plugin from your home directory into PARI: <lang parigp>install("plug_md5", "s", "MD5", "~/libmd5.so");
MD5("The quick brown fox jumped over the lazy dog's back") </lang>
Output:
"e38ca1d920c4b8b8d3946b2c72f01680"
Pascal
Pascal has a built-in unit called md5. It can be used to get a digest both for a string and a file.
program GetMd5; uses md5; var strEncrypted : string; begin strEncrypted := md5Print(md5String('The quick brown fox jumped over the lazy dog''s back')); writeln(strEncrypted); readln; end.
output:
e38ca1d920c4b8b8d3946b2c72f01680
To digest a file, use md5Print(md5File('myfile.txt')) where myfile.txt is a file.
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>
Perl 6
Library Digest::MD5 <lang perl6>use Digest::MD5; say Digest::MD5.md5_hex: "The quick brown fox jumped over the lazy dog's back";</lang>
PHP
<lang php>$string = "The quick brown fox jumped over the lazy dog's back"; echo md5( $string );</lang>
PicoLisp
Using the openssl library (the 'native' function is only in the 64-bit version available): <lang PicoLisp>(let Str "The quick brown fox jumped over the lazy dog's back"
(pack (mapcar '((B) (pad 2 (hex B))) (native "libcrypto.so" "MD5" '(B . 16) Str (length Str) '(NIL (16))) ) ) )</lang>
Output:
-> "E38CA1D920C4B8B8D3946B2C72F01680"
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>
PureBasic
<lang purebasic>test$ = "The quick brown fox jumped over the lazy dog's back" Debug MD5Fingerprint(@test$, StringByteLength(test$))</lang>
Python
Using builtin libraries:
- Python 3.x, 2.5 and later 2.x versions
<lang python>>>> import hashlib >>> # RFC 1321 test suite: >>> tests = (
(b"", 'd41d8cd98f00b204e9800998ecf8427e'), (b"a", '0cc175b9c0f1b6a831c399e269772661'), (b"abc", '900150983cd24fb0d6963f7d28e17f72'), (b"message digest", 'f96b697d7cb7938d525a2f31aaf161d0'), (b"abcdefghijklmnopqrstuvwxyz", 'c3fcd3d76192e4007dfb496cca67e13b'), (b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 'd174ab98d277d9f5a5611c2c9f419d9f'), (b"12345678901234567890123456789012345678901234567890123456789012345678901234567890", '57edf4a22be3c955ac49da2e2107b67a') )
>>> for text, golden in tests: assert hashlib.md5(text).hexdigest() == golden
>>> </lang>
- 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>
Racket
<lang racket>
- lang racket
(require file/md5)
(md5 "") (md5 "a") (md5 "abc") (md5 "message digest") (md5 "abcdefghijklmnopqrstuvwxyz") (md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") (md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890") </lang>
Output:
#"d41d8cd98f00b204e9800998ecf8427e" #"0cc175b9c0f1b6a831c399e269772661" #"900150983cd24fb0d6963f7d28e17f72" #"f96b697d7cb7938d525a2f31aaf161d0" #"c3fcd3d76192e4007dfb496cca67e13b" #"d174ab98d277d9f5a5611c2c9f419d9f" #"57edf4a22be3c955ac49da2e2107b67a"
REBOL
<lang rebol>>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 == #{08A008A01D498C404B0C30852B39D3B8}</lang>
REXX
<lang rexx>/*REXX program tests the MD5 procedure (below) as per a test suite the IETF RFC (1321).*/ msg.1 = /*─────MD5 test suite [from above doc].*/ msg.2 = 'a' msg.3 = 'abc' msg.4 = 'message digest' msg.5 = 'abcdefghijklmnopqrstuvwxyz' msg.6 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' msg.7 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890 msg.0 = 7 /* [↑] last value doesn't need quotes.*/
do m=1 for msg.0; say /*process each of the seven messages. */ say ' in =' msg.m /*display the in message. */ say 'out =' MD5(msg.m) /* " " out " */ end /*m*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ MD5: procedure; parse arg !; numeric digits 20 /*insure there's enough decimal digits.*/
a='67452301'x; b="efcdab89"x; c='98badcfe'x; d="10325476"x; x00='0'x; x80="80"x #=length(!) /*length in bytes of the input message.*/ L=#*8//512; if L<448 then plus=448-L /*is the length less than 448 ? */ if L>448 then plus=960-L /* " " " greater " " */ if L=448 then plus=512 /* " " " equal to " */ /* [↓] a little of this, ··· */ $=! || x80 || copies(x00, plus%8 -1)reverse(right(d2c(8 * #), 4, x00)) || '00000000'x /* [↑] ··· and a little of that.*/ do j=0 to length($)%64-1 /*process the message (lots of steps).*/ a_=a; b_=b; c_=c; d_=d /*save the original values for later.*/ chunk=j*64 /*calculate the size of the chunks. */ do k=1 for 16 /*process the message in chunks. */ !.k=reverse( substr($, chunk + 1 + 4*(k-1), 4) ) /*magic stuff.*/ end /*k*/
a = .part1( a, b, c, d, 0, 7, 3614090360) /*■■■■ 1 ■■■■*/ d = .part1( d, a, b, c, 1, 12, 3905402710) /*■■■■ 2 ■■■■*/ c = .part1( c, d, a, b, 2, 17, 606105819) /*■■■■ 3 ■■■■*/ b = .part1( b, c, d, a, 3, 22, 3250441966) /*■■■■ 4 ■■■■*/ a = .part1( a, b, c, d, 4, 7, 4118548399) /*■■■■ 5 ■■■■*/ d = .part1( d, a, b, c, 5, 12, 1200080426) /*■■■■ 6 ■■■■*/ c = .part1( c, d, a, b, 6, 17, 2821735955) /*■■■■ 7 ■■■■*/ b = .part1( b, c, d, a, 7, 22, 4249261313) /*■■■■ 8 ■■■■*/ a = .part1( a, b, c, d, 8, 7, 1770035416) /*■■■■ 9 ■■■■*/ d = .part1( d, a, b, c, 9, 12, 2336552879) /*■■■■ 10 ■■■■*/ c = .part1( c, d, a, b, 10, 17, 4294925233) /*■■■■ 11 ■■■■*/ b = .part1( b, c, d, a, 11, 22, 2304563134) /*■■■■ 12 ■■■■*/ a = .part1( a, b, c, d, 12, 7, 1804603682) /*■■■■ 13 ■■■■*/ d = .part1( d, a, b, c, 13, 12, 4254626195) /*■■■■ 14 ■■■■*/ c = .part1( c, d, a, b, 14, 17, 2792965006) /*■■■■ 15 ■■■■*/ b = .part1( b, c, d, a, 15, 22, 1236535329) /*■■■■ 16 ■■■■*/ a = .part2( a, b, c, d, 1, 5, 4129170786) /*■■■■ 17 ■■■■*/ d = .part2( d, a, b, c, 6, 9, 3225465664) /*■■■■ 18 ■■■■*/ c = .part2( c, d, a, b, 11, 14, 643717713) /*■■■■ 19 ■■■■*/ b = .part2( b, c, d, a, 0, 20, 3921069994) /*■■■■ 20 ■■■■*/ a = .part2( a, b, c, d, 5, 5, 3593408605) /*■■■■ 21 ■■■■*/ d = .part2( d, a, b, c, 10, 9, 38016083) /*■■■■ 22 ■■■■*/ c = .part2( c, d, a, b, 15, 14, 3634488961) /*■■■■ 23 ■■■■*/ b = .part2( b, c, d, a, 4, 20, 3889429448) /*■■■■ 24 ■■■■*/ a = .part2( a, b, c, d, 9, 5, 568446438) /*■■■■ 25 ■■■■*/ d = .part2( d, a, b, c, 14, 9, 3275163606) /*■■■■ 26 ■■■■*/ c = .part2( c, d, a, b, 3, 14, 4107603335) /*■■■■ 27 ■■■■*/ b = .part2( b, c, d, a, 8, 20, 1163531501) /*■■■■ 28 ■■■■*/ a = .part2( a, b, c, d, 13, 5, 2850285829) /*■■■■ 29 ■■■■*/ d = .part2( d, a, b, c, 2, 9, 4243563512) /*■■■■ 30 ■■■■*/ c = .part2( c, d, a, b, 7, 14, 1735328473) /*■■■■ 31 ■■■■*/ b = .part2( b, c, d, a, 12, 20, 2368359562) /*■■■■ 32 ■■■■*/ a = .part3( a, b, c, d, 5, 4, 4294588738) /*■■■■ 33 ■■■■*/ d = .part3( d, a, b, c, 8, 11, 2272392833) /*■■■■ 34 ■■■■*/ c = .part3( c, d, a, b, 11, 16, 1839030562) /*■■■■ 35 ■■■■*/ b = .part3( b, c, d, a, 14, 23, 4259657740) /*■■■■ 36 ■■■■*/ a = .part3( a, b, c, d, 1, 4, 2763975236) /*■■■■ 37 ■■■■*/ d = .part3( d, a, b, c, 4, 11, 1272893353) /*■■■■ 38 ■■■■*/ c = .part3( c, d, a, b, 7, 16, 4139469664) /*■■■■ 39 ■■■■*/ b = .part3( b, c, d, a, 10, 23, 3200236656) /*■■■■ 40 ■■■■*/ a = .part3( a, b, c, d, 13, 4, 681279174) /*■■■■ 41 ■■■■*/ d = .part3( d, a, b, c, 0, 11, 3936430074) /*■■■■ 42 ■■■■*/ c = .part3( c, d, a, b, 3, 16, 3572445317) /*■■■■ 43 ■■■■*/ b = .part3( b, c, d, a, 6, 23, 76029189) /*■■■■ 44 ■■■■*/ a = .part3( a, b, c, d, 9, 4, 3654602809) /*■■■■ 45 ■■■■*/ d = .part3( d, a, b, c, 12, 11, 3873151461) /*■■■■ 46 ■■■■*/ c = .part3( c, d, a, b, 15, 16, 530742520) /*■■■■ 47 ■■■■*/ b = .part3( b, c, d, a, 2, 23, 3299628645) /*■■■■ 48 ■■■■*/ a = .part4( a, b, c, d, 0, 6, 4096336452) /*■■■■ 49 ■■■■*/ d = .part4( d, a, b, c, 7, 10, 1126891415) /*■■■■ 50 ■■■■*/ c = .part4( c, d, a, b, 14, 15, 2878612391) /*■■■■ 51 ■■■■*/ b = .part4( b, c, d, a, 5, 21, 4237533241) /*■■■■ 52 ■■■■*/ a = .part4( a, b, c, d, 12, 6, 1700485571) /*■■■■ 53 ■■■■*/ d = .part4( d, a, b, c, 3, 10, 2399980690) /*■■■■ 54 ■■■■*/ c = .part4( c, d, a, b, 10, 15, 4293915773) /*■■■■ 55 ■■■■*/ b = .part4( b, c, d, a, 1, 21, 2240044497) /*■■■■ 56 ■■■■*/ a = .part4( a, b, c, d, 8, 6, 1873313359) /*■■■■ 57 ■■■■*/ d = .part4( d, a, b, c, 15, 10, 4264355552) /*■■■■ 58 ■■■■*/ c = .part4( c, d, a, b, 6, 15, 2734768916) /*■■■■ 59 ■■■■*/ b = .part4( b, c, d, a, 13, 21, 1309151649) /*■■■■ 60 ■■■■*/ a = .part4( a, b, c, d, 4, 6, 4149444226) /*■■■■ 61 ■■■■*/ d = .part4( d, a, b, c, 11, 10, 3174756917) /*■■■■ 62 ■■■■*/ c = .part4( c, d, a, b, 2, 15, 718787259) /*■■■■ 63 ■■■■*/ b = .part4( b, c, d, a, 9, 21, 3951481745) /*■■■■ 64 ■■■■*/ a = .a(a_,a); b=.a(b_,b); c=.a(c_,c); d=.a(d_,d) end /*j*/
return c2x( reverse(a) )c2x( reverse(b) )c2x( reverse(c) )c2x( reverse(d) )
/*──────────────────────────────────────────────────────────────────────────────────────*/ .a: return right(d2c(c2d(arg(1)) + c2d(arg(2))), 4, '0'x) .h: return bitxor(bitxor(arg(1), arg(2)), arg(3)) .i: return bitxor(arg(2), bitor(arg(1), bitxor(arg(3), 'ffffffff'x))) .f: return bitor(bitand(arg(1),arg(2)), bitand(bitxor(arg(1), 'ffffffff'x), arg(3))) .g: return bitor(bitand(arg(1),arg(3)), bitand(arg(2), bitxor(arg(3), 'ffffffff'x))) .Lr: procedure; parse arg _,#; if #==0 then return _ /*left rotate.*/
?=x2b(c2x(_)); return x2c(b2x(right(? || left(?, #), length(?))))
.part1: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.f(x,y,z))+c2d(!.n)),4,'0'x),m),x)
.part2: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.g(x,y,z))+c2d(!.n)),4,'0'x),m),x)
.part3: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.h(x,y,z))+c2d(!.n)),4,'0'x),m),x)
.part4: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
return .a(.Lr(right(d2c(c2d(w)+c2d(.i(x,y,z))+c2d(!.n)+_),4,'0'x),m),x)</lang>
output
in = out = D41D8CD98F00B204E9800998ECF8427E in = a out = 0CC175B9C0F1B6A831C399E269772661 in = abc out = 900150983CD24FB0D6963F7D28E17F72 in = message digest out = F96B697D7CB7938D525A2F31AAF161D0 in = abcdefghijklmnopqrstuvwxyz out = C3FCD3D76192E4007DFB496CCA67E13B in = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 out = D174AB98D277D9F5A5611C2C9F419D9F in = 12345678901234567890123456789012345678901234567890123456789012345678901234567890 out = 57EDF4A22BE3C955AC49DA2E2107B67A
RLaB
RLaB has a built-in function hash,
which implements hash functions fn as "md2", "md5", "sha", "sha1", "dss", "dss1" and "ripemd160", for given string vector ss and new-line delimiter nl. The last is here so that a hash of a string vector calculated in RLaB is the same as the hash of the same string vector written to a file.
<lang RLaB>>> x = "The quick brown fox jumped over the lazy dog's back" The quick brown fox jumped over the lazy dog's back
>> hash("md5", x) e38ca1d920c4b8b8d3946b2c72f01680</lang>
Ring
<lang ring> See MD5("my string!") + nl
- output : a83a049fbe50cf7334caa86bf16a3520
</lang>
Ruby
<lang ruby>require 'digest' Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back")
- => "e38ca1d920c4b8b8d3946b2c72f01680"</lang>
Rust
Cargo.toml <lang toml> [dependencies] rust-crypto = "0.2" </lang>
src/main.rs <lang rust> extern crate crypto;
use crypto::digest::Digest; use crypto::md5::Md5;
fn main() {
let mut sh = Md5::new(); sh.input_str("The quick brown fox jumped over the lazy dog's back"); println!("{}", sh.result_str());
} </lang>
Scala
<lang scala>object RosettaMD5 extends App {
def MD5(s: String): String = { // Besides "MD5", "SHA-256", and other hashes are available val m = java.security.MessageDigest.getInstance("MD5").digest(s.getBytes("UTF-8")) m.map("%02x".format(_)).mkString }
assert("d41d8cd98f00b204e9800998ecf8427e" == MD5("")) assert("0cc175b9c0f1b6a831c399e269772661" == MD5("a")) assert("900150983cd24fb0d6963f7d28e17f72" == MD5("abc")) assert("f96b697d7cb7938d525a2f31aaf161d0" == MD5("message digest")) assert("c3fcd3d76192e4007dfb496cca67e13b" == MD5("abcdefghijklmnopqrstuvwxyz")) assert("e38ca1d920c4b8b8d3946b2c72f01680" == MD5("The quick brown fox jumped over the lazy dog's back")) assert("d174ab98d277d9f5a5611c2c9f419d9f" == MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")) assert("57edf4a22be3c955ac49da2e2107b67a" == MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890")) 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(md5("The quick brown fox jumped over the lazy dog's back"))); end func;</lang>
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Sidef
<lang ruby>var digest = frequire('Digest::MD5'); say digest.md5_hex("The quick brown fox jumped over the lazy dog's back");</lang>
The same in OO manner <lang ruby>var md5 = require('Digest::MD5').new; md5.add("The quick brown fox jumped over the lazy dog's back"); say md5.hexdigest;</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
Using utility classes:
<lang smalltalk>PackageLoader fileInPackage: 'Digest' ! (MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dogs back') displayNl.</lang>
<lang smalltalk>(MD5Stream hashValueOf: 'The quick brown fox jumped over the lazy dogs back') printCR.</lang>
SQL
<lang sql>SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')</lang>
Suneido
<lang Suneido>Md5('The quick brown fox jumped over the lazy dog\'s back')</lang>
Tcl
<lang tcl>package require md5 puts [md5::md5 -hex "The quick brown fox jumped over the lazy dog's back"]
- ==> E38CA1D920C4B8B8D3946B2C72F01680</lang>
UNIX Shell
Shells execute system commands (such as md5sum, in this case). We must pass "-n" to echo, so no trailing newline is appended, which would change the MD5-hash.
GNU coreutils has md5sum: <lang bash>echo -n "The quick brown fox jumped over the lazy dog's back" | md5sum</lang>
Several BSD systems have md5: <lang bash>echo -n "The quick brown fox jumped over the lazy dog's back" | md5</lang>
<lang bash>echo -n "The quick brown fox jumped over the lazy dog's back" |
openssl md5 | sed 's/.*= //'</lang>
zkl
md5 is a built in utility <lang zkl>Utils.MD5.calc("message digest"); //-->"f96b697d7cb7938d525a2f31aaf161d0" Utils.MD5.calc("abcdefghijklmnopqrstuvwxyz"); //-->"c3fcd3d76192e4007dfb496cca67e13b"</lang>
- Programming Tasks
- Checksums
- 8th
- Ada
- ALGOL 68
- AutoHotkey
- BBC BASIC
- C
- OpenSSL
- C++
- Poco Crypto
- C sharp
- Caché ObjectScript
- Clojure
- Common Lisp
- Ironclad
- CFFI
- D
- Tango
- Delphi
- E
- Emacs Lisp
- Erlang
- Factor
- Forth
- Forth Foundation Library
- Frink
- Go
- Groovy
- Haskell
- Cryptonite
- Io
- Icon
- Unicon
- J
- Java
- Julia
- Lasso
- Liberty BASIC
- LiveCode
- Lua
- Maple
- Mathematica
- MATLAB
- MOO
- Nemerle
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Crypto
- Objeck
- Objective-C
- OCaml
- Octave
- OpenEdge/Progress
- PARI/GP
- Perl
- Perl 6
- PHP
- PicoLisp
- Pike
- PowerShell
- PureBasic
- Python
- R
- Racket
- REBOL
- REXX
- RLaB
- Ring
- Ruby
- Rust
- Scala
- Seed7
- Sidef
- Slate
- Smalltalk
- SQL
- Suneido
- Tcl
- Tcllib
- UNIX Shell
- Zkl
- GUISS/Omit