MD5: Difference between revisions
→Nu: add |
|||
(186 intermediate revisions by 93 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Checksums}} |
{{task|Checksums}} |
||
;Task: |
|||
Encode a string using an MD5 algorithm. The algorithm can be found on [[wp:Md5#Algorithm|wikipedia]]. |
|||
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://www.ietf.org/rfc/rfc1321.txt IETF RFC (1321) for MD5]. Additional the RFC provides more precise information on the algorithm than the Wikipedia article. |
|||
Optionally, validate your implementation by running all of the test values in [http://tools.ietf.org/html/rfc1321 IETF RFC (1321) for MD5]. |
|||
Additionally, RFC 1321 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.}} |
|||
If the solution on this page is a library solution, see [[MD5/Implementation]] for an implementation from scratch. |
|||
<br><br> |
|||
=={{header|8th}}== |
|||
<syntaxhighlight lang="forth"> |
|||
"md5" cr:hash! "Some text" cr:hash cr:hash>s |
|||
. cr bye |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<tt> |
|||
9db5682a4d778ca2cb79580bdb67083f |
|||
</tt> |
|||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }} |
|||
<syntaxhighlight lang="aarch64 assembly"> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
|||
/* program MD5_64.s */ |
|||
/*******************************************/ |
|||
/* Constantes file */ |
|||
/*******************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly*/ |
|||
.include "../includeConstantesARM64.inc" |
|||
.equ MD5_DIGEST_LENGTH, 16 |
|||
.equ ZWORKSIZE, 1000 |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szMessRosetta: .asciz "Rosetta Code" |
|||
szMessTest1: .asciz "" |
|||
szMessTest2: .asciz "abc" |
|||
szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz" |
|||
szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890" |
|||
szMessTest5: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
|||
szMessFinPgm: .asciz "Program End ok.\n" |
|||
szMessResult: .asciz "Result for " |
|||
szMessResult1: .asciz " => " |
|||
szMessSizeError: .asciz "\033[31mWork area too small !! \033[0m \n" |
|||
szCarriageReturn: .asciz "\n" |
|||
/* array constantes K */ |
|||
tbConstK: .int 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee |
|||
.int 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501 |
|||
.int 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be |
|||
.int 0x6b901122,0xfd987193,0xa679438e,0x49b40821 |
|||
.int 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa |
|||
.int 0xd62f105d,0x2441453,0xd8a1e681,0xe7d3fbc8 |
|||
.int 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed |
|||
.int 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a |
|||
.int 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c |
|||
.int 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70 |
|||
.int 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x4881d05 |
|||
.int 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665 |
|||
.int 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039 |
|||
.int 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1 |
|||
.int 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1 |
|||
.int 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 |
|||
/* array rotation coef R */ |
|||
tbRotaR: .int 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 |
|||
.int 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20 |
|||
.int 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23 |
|||
.int 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 |
|||
tbConstH: .int 0x67452301 // H0 |
|||
.int 0xEFCDAB89 // H1 |
|||
.int 0x98BADCFE // H2 |
|||
.int 0x10325476 // H3 |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
.align 4 |
|||
//iNbBlocs: .skip 8 |
|||
sZoneConv: .skip 24 |
|||
sZoneResult: .skip 24 |
|||
tbH: .skip 4 * 4 // 4 variables H |
|||
sZoneTrav: .skip ZWORKSIZE |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: // entry of program |
|||
ldr x0,qAdrszMessTest1 |
|||
bl computeExemple |
|||
ldr x0,qAdrszMessTest2 |
|||
bl computeExemple |
|||
ldr x0,qAdrszMessTest3 |
|||
bl computeExemple |
|||
ldr x0,qAdrszMessTest4 |
|||
bl computeExemple |
|||
ldr x0,qAdrszMessTest5 |
|||
bl computeExemple |
|||
ldr x0,qAdrszMessFinPgm |
|||
bl affichageMess // display message |
|||
100: // standard end of the program |
|||
mov x0,0 // return code |
|||
mov x8,EXIT // request to exit program |
|||
svc 0 // perform the system call |
|||
qAdrszCarriageReturn: .quad szCarriageReturn |
|||
qAdrszMessResult: .quad szMessResult |
|||
qAdrszMessResult1: .quad szMessResult1 |
|||
qAdrszMessRosetta: .quad szMessRosetta |
|||
qAdrszMessTest1: .quad szMessTest1 |
|||
qAdrszMessTest2: .quad szMessTest2 |
|||
qAdrszMessTest3: .quad szMessTest3 |
|||
qAdrszMessTest4: .quad szMessTest4 |
|||
qAdrszMessTest5: .quad szMessTest5 |
|||
qAdrsZoneTrav: .quad sZoneTrav |
|||
qAdrsZoneConv: .quad sZoneConv |
|||
qAdrszMessFinPgm: .quad szMessFinPgm |
|||
/***********************************************/ |
|||
/* compute exemple */ |
|||
/***********************************************/ |
|||
/* x0 contains the address of the message */ |
|||
computeExemple: |
|||
stp x18,lr,[sp,-16]! // save registers |
|||
mov x18,x0 |
|||
bl computeMD5 // call routine MD5 |
|||
ldr x0,qAdrszMessResult |
|||
bl affichageMess |
|||
mov x0,x18 |
|||
bl affichageMess |
|||
ldr x0,qAdrszMessResult1 |
|||
bl affichageMess |
|||
ldr x0, qAdrsZoneResult |
|||
bl displayMD5 |
|||
100: |
|||
ldp x18,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* compute MD5 */ |
|||
/******************************************************************/ |
|||
/* x0 contains the address of the message */ |
|||
computeMD5: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
ldr x1,qAdrsZoneTrav |
|||
mov x2,#0 // counter length |
|||
1: // copy string in work area |
|||
cmp x2,ZWORKSIZE |
|||
bge 99f |
|||
ldrb w3,[x0,x2] |
|||
strb w3,[x1,x2] |
|||
cmp x3,#0 |
|||
add x4,x2,1 |
|||
csel x2,x4,x2,ne |
|||
bne 1b |
|||
// add bit et compute length |
|||
lsl x6,x2,#3 // initial message length in bits |
|||
mov x3,#0b10000000 // add bit 1 at end of string |
|||
strb w3,[x1,x2] |
|||
add x2,x2,#1 // length in bytes |
|||
lsl x4,x2,#3 // length in bits |
|||
mov x3,#0 |
|||
2: |
|||
lsr x5,x2,#6 // padding block 512 bytes |
|||
lsl x5,x5,#6 |
|||
sub x5,x2,x5 |
|||
cmp x5,#56 |
|||
beq 3f // yes -> end add |
|||
strb w3,[x1,x2] // add zero at message end |
|||
add x2,x2,#1 // increment length bytes |
|||
add x4,x4,#8 // increment length in bits |
|||
b 2b |
|||
3: |
|||
str x6,[x1,x2] // and store at end |
|||
ldr x7,qAdrtbConstH // constantes H address |
|||
ldr x4,qAdrtbH // start area H |
|||
mov x5,#0 |
|||
4: // init array H with start constantes |
|||
ldr w6,[x7,x5,lsl #2] // load constante |
|||
str w6,[x4,x5,lsl #2] // and store |
|||
add x5,x5,#1 |
|||
cmp x5,#4 // constantes number |
|||
blt 4b |
|||
// split into block of 64 bytes |
|||
add x2,x2,#4 // TODO : à revoir |
|||
lsr x4,x2,#6 // blocks number |
|||
mov x7,#0 // no de block et x1 contient l'adresse zone de travail |
|||
ldr x3,qAdrtbConstK // K constantes address |
|||
ldr x5,qAdrtbRotaR // R rotation address |
|||
5: // begin loop of each block of 64 bytes |
|||
// init variable a b c d with H0 H1 H2 H3 |
|||
ldr x0,qAdrtbH |
|||
ldr w8,[x0] // a |
|||
ldr w9,[x0,#4] // b |
|||
ldr w10,[x0,#8] // c |
|||
ldr w11,[x0,#12] // d |
|||
mov x6,#0 // indice t |
|||
/* x2 address begin each block */ |
|||
ldr x1,qAdrsZoneTrav |
|||
add x2,x1,x7,lsl #6 // compute block begin indice * 4 * 16 |
|||
6: // begin loop one |
|||
cmp x6,15 |
|||
bgt 7f |
|||
// cas 1 f := (b et c) ou ((non b) et d) |
|||
// g := i |
|||
and w12,w9,w10 |
|||
mvn w13,w9 |
|||
and w13,w13,w11 |
|||
orr w12,w12,w13 // f |
|||
mov x14,x6 // g |
|||
b 10f |
|||
7: |
|||
cmp x6,31 |
|||
bgt 8f |
|||
// f := (d et b) ou ((non d) et c) |
|||
// g := (5×i + 1) mod 16 |
|||
and w12,w11,w9 |
|||
mvn w13,w11 |
|||
and w13,w13,w10 |
|||
orr w12,w12,w13 // f |
|||
mov x13,5 |
|||
mul x13,x6,x13 |
|||
add x13,x13,1 |
|||
lsr x15,x13,4 |
|||
lsl x15,x15,4 |
|||
sub x14,x13,x15 |
|||
b 10f |
|||
8: |
|||
cmp x6,47 |
|||
bgt 9f |
|||
// f := b xor c xor d |
|||
// g := (3×i + 5) mod 16 |
|||
eor w12,w9,w10 |
|||
eor w12,w12,w11 |
|||
mov x13,3 |
|||
mul x13,x6,x13 |
|||
add x13,x13,5 |
|||
lsr x15,x13,4 |
|||
lsl x15,x15,4 |
|||
sub x14,x13,x15 |
|||
b 10f |
|||
9: |
|||
// f := c xor (b ou (non d)) |
|||
// g := (7×i) mod 16 |
|||
mvn w13,w11 |
|||
orr w13,w13,w9 |
|||
eor w12,w13,w10 // f |
|||
mov x13,7 |
|||
mul x13,x6,x13 |
|||
lsr x15,x13,4 |
|||
lsl x15,x15,4 |
|||
sub x14,x13,x15 // g |
|||
10: |
|||
mov w15,w11 |
|||
mov w11,w10 // d = c |
|||
mov w10,w9 // c = b |
|||
add w16,w8,w12 // a + f |
|||
ldr w17,[x2,x14,lsl #2] |
|||
add w16,w16,w17 // + valeur bloc g |
|||
ldr w13,[x3,x6,lsl #2] |
|||
add w16,w16,w13 // + valeur constante K de i |
|||
ldr w17,[x5,x6,lsl #2] // rotate left value |
|||
mov w13,32 |
|||
sub w17,w13,w17 |
|||
ror w13,w16,w17 |
|||
add w9,w9,w13 // new b |
|||
mov w8, w15 // new a |
|||
add x6,x6,1 |
|||
cmp x6,63 |
|||
ble 6b |
|||
ldr x0,qAdrtbH |
|||
ldr w1,[x0] // H0 |
|||
add w1,w1,w8 // + a |
|||
str w1,[x0] |
|||
ldr w1,[x0,#4] // H1 |
|||
add w1,w1,w9 // + b |
|||
str w1,[x0,#4] |
|||
ldr w1,[x0,#8] // H2 |
|||
add w1,w1,w10 // + c |
|||
str w1,[x0,#8] |
|||
ldr w1,[x0,#12] // H3 |
|||
add w1,w1,w11 // + d |
|||
str w1,[x0,#12] |
|||
// other bloc |
|||
add x7,x7,1 // increment block |
|||
cmp x7,x4 // maxi ? |
|||
ble 5b |
|||
// compute final result |
|||
ldr x0,qAdrtbH // start area H |
|||
ldr x2,qAdrsZoneResult |
|||
ldr w1,[x0] |
|||
str w1,[x2] |
|||
ldr w1,[x0,#4] |
|||
str w1,[x2,#4] |
|||
ldr w1,[x0,#8] |
|||
str w1,[x2,#8] |
|||
ldr w1,[x0,#12] |
|||
str w1,[x2,#12] |
|||
mov x0,#0 // routine OK |
|||
b 100f |
|||
99: // size error |
|||
ldr x0,qAdrszMessSizeError |
|||
bl affichageMess |
|||
mov x0,-1 |
|||
100: |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
qAdrtbConstH: .quad tbConstH |
|||
qAdrtbConstK: .quad tbConstK |
|||
qAdrtbRotaR: .quad tbRotaR |
|||
qAdrtbH: .quad tbH |
|||
qAdrsZoneResult: .quad sZoneResult |
|||
qAdrszMessSizeError: .quad szMessSizeError |
|||
/******************************************************************/ |
|||
/* display hash MD5 */ |
|||
/******************************************************************/ |
|||
/* x0 contains the address of hash */ |
|||
displayMD5: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
mov x3,x0 |
|||
mov x2,#0 |
|||
1: |
|||
ldr w0,[x3,x2,lsl #2] // load 4 bytes |
|||
rev w0,w0 // reverse bytes |
|||
ldr x1,qAdrsZoneConv |
|||
bl conversion16_4W // conversion hexa |
|||
ldr x0,qAdrsZoneConv |
|||
bl affichageMess |
|||
add x2,x2,#1 |
|||
cmp x2,#MD5_DIGEST_LENGTH / 4 |
|||
blt 1b // and loop |
|||
ldr x0,qAdrszCarriageReturn |
|||
bl affichageMess // display message |
|||
100: |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* conversion hexadecimal register 32 bits */ |
|||
/******************************************************************/ |
|||
/* x0 contains value and x1 address zone receptrice */ |
|||
conversion16_4W: |
|||
stp x0,lr,[sp,-48]! // save registres |
|||
stp x1,x2,[sp,32] // save registres |
|||
stp x3,x4,[sp,16] // save registres |
|||
mov x2,#28 // start bit position |
|||
mov x4,#0xF0000000 // mask |
|||
mov x3,x0 // save entry value |
|||
1: // start loop |
|||
and x0,x3,x4 // value register and mask |
|||
lsr x0,x0,x2 // right shift |
|||
cmp x0,#10 // >= 10 ? |
|||
bge 2f // yes |
|||
add x0,x0,#48 // no is digit |
|||
b 3f |
|||
2: |
|||
add x0,x0,#55 // else is a letter A-F |
|||
3: |
|||
strb w0,[x1],#1 // load result and + 1 in address |
|||
lsr x4,x4,#4 // shift mask 4 bits left |
|||
subs x2,x2,#4 // decrement counter 4 bits <= zero ? |
|||
bge 1b // no -> loop |
|||
100: // fin standard de la fonction |
|||
ldp x3,x4,[sp,16] // restaur des 2 registres |
|||
ldp x1,x2,[sp,32] // restaur des 2 registres |
|||
ldp x0,lr,[sp],48 // restaur des 2 registres |
|||
ret |
|||
/********************************************************/ |
|||
/* File Include fonctions */ |
|||
/********************************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly */ |
|||
.include "../includeARM64.inc" |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Result for => D41D8CD98F00B204E9800998ECF8427E |
|||
Result for abc => 900150983CD24FB0D6963F7D28E17F72 |
|||
Result for abcdefghijklmnopqrstuvwxyz => C3FCD3D76192E4007DFB496CCA67E13B |
|||
Result for 12345678901234567890123456789012345678901234567890123456789012345678901234567890 => 57EDF4A22BE3C955AC49DA2E2107B67A |
|||
Result for ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 => D174AB98D277D9F5A5611C2C9F419D9F |
|||
Program End ok. |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
{{works with|GNAT}} |
{{works with|GNAT}} |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
with GNAT.MD5; |
with GNAT.MD5; |
||
Line 13: | Line 423: | ||
begin |
begin |
||
Put(GNAT.MD5.Digest("Foo bar baz")); |
Put(GNAT.MD5.Digest("Foo bar baz")); |
||
end MD5_Digest;</ |
end MD5_Digest;</syntaxhighlight> |
||
=={{ |
=={{header|ALGOL 68}}== |
||
<syntaxhighlight 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 |
|||
</syntaxhighlight> |
|||
=={{header|APL}}== |
|||
{{works with|Dyalog APL}} |
|||
<syntaxhighlight lang="apl"> |
|||
md5←{ |
|||
⍝ index origin zero |
|||
⎕IO←0 |
|||
⍝ decoding UTF-8 & padding |
|||
M←(⊢,(0⍴⍨512|448-512|≢))1,⍨l←,⍉(8⍴2)⊤'UTF-8'⎕UCS ⍵ |
|||
⍝ add length |
|||
M,←,⍉(8⍴2)⊤⌽(8⍴256)⊤≢l |
|||
⍝ init registers |
|||
A←16⊥6 7 4 5 2 3 0 1 |
|||
B←16⊥14 15 12 13 10 11 8 9 |
|||
C←16⊥9 8 11 10 13 12 15 14 |
|||
D←16⊥1 0 3 2 5 4 7 6 |
|||
⍝ T table |
|||
T←⌊(2*32)×|1○1+⍳64 |
|||
⍝ index table |
|||
K←16|i,(1+5×i),(5+3×i),7×i←⍳16 |
|||
⍝ rot table |
|||
S←,1 0 2⍉4 4 4⍴7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21 |
|||
⍝ truncate ⍵ to 32 bit & rot left ⍺ |
|||
rot←{2⊥⍺⌽(32⍴2)⊤⍵} |
|||
proc←{ |
|||
⍝ pack 512 bits into 32 bit words & |
|||
⍝ precompute X[k] + T[i] |
|||
l←T+(⊂K)⌷256⊥⍉⌽16 4⍴2⊥⍉64 8⍴⍺ |
|||
fn←{ |
|||
⍝ a b c d to binary |
|||
a b c d←↓⍉(32⍴2)⊤⍵ |
|||
⍝ a + F(b,c,d) |
|||
⍺<16:S[⍺]rot l[⍺]+2⊥a+d≠b∧c≠d |
|||
⍺<32:S[⍺]rot l[⍺]+2⊥a+(b∧d)∨(c∧~d) |
|||
⍺<48:S[⍺]rot l[⍺]+2⊥a+b≠c≠d |
|||
S[⍺]rot l[⍺]+2⊥a+c≠b∨~d |
|||
} |
|||
(2*32)|⍵+⊃{¯1⌽((⍵[1]+⍺ fn ⍵)@0)⍵}/(⌽⍳64),⊂⍵ |
|||
} |
|||
⍝ process each 512 bits |
|||
loop←{⍬≡⍺:⍵ ⋄ (512↓⍺)∇(512↑⍺)proc ⍵} |
|||
⍝ output registers |
|||
(⎕D,⎕A)[,⍉(2⍴16)⊤,⍉⊖(4⍴256)⊤M loop A B C D] |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">print digest "The quick brown fox jumped over the lazy dog's back"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
=={{header|ARM Assembly}}== |
|||
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}} |
|||
<syntaxhighlight lang="arm assembly"> |
|||
/* ARM assembly Raspberry PI */ |
|||
/* program MD5.s */ |
|||
/* REMARK 1 : this program use routines in a include file |
|||
see task Include a file language arm assembly |
|||
for the routine affichageMess conversion10 |
|||
see at end of this program the instruction include */ |
|||
/* for constantes see task include a file in arm assembly */ |
|||
/************************************/ |
|||
/* Constantes */ |
|||
/************************************/ |
|||
.include "../constantes.inc" |
|||
.equ LGHASH, 16 // result length |
|||
.equ ZWORKSIZE, 1000 // work area size |
|||
/*******************************************/ |
|||
/* Structures */ |
|||
/********************************************/ |
|||
/* example structure variables */ |
|||
.struct 0 |
|||
var_a: // a |
|||
.struct var_a + 4 |
|||
var_b: // b |
|||
.struct var_b + 4 |
|||
var_c: // c |
|||
.struct var_c + 4 |
|||
var_d: // d |
|||
.struct var_d + 4 |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szMessTest1: .asciz "abc" |
|||
szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890" |
|||
szMessTest2: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
|||
szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz" |
|||
szMessFinPgm: .asciz "Program End ok.\n" |
|||
szMessResult: .asciz "Result for " |
|||
szMessResult1: .asciz " => " |
|||
szMessSizeError: .asciz "\033[31mWork area too small !! \033[0m \n" |
|||
szCarriageReturn: .asciz "\n" |
|||
.align 4 |
|||
/* array constantes K */ |
|||
tbConstK: .int 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee |
|||
.int 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501 |
|||
.int 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be |
|||
.int 0x6b901122,0xfd987193,0xa679438e,0x49b40821 |
|||
.int 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa |
|||
.int 0xd62f105d,0x2441453,0xd8a1e681,0xe7d3fbc8 |
|||
.int 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed |
|||
.int 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a |
|||
.int 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c |
|||
.int 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70 |
|||
.int 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x4881d05 |
|||
.int 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665 |
|||
.int 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039 |
|||
.int 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1 |
|||
.int 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1 |
|||
.int 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 |
|||
/* array rotation coef R */ |
|||
tbRotaR: .int 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 |
|||
.int 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20 |
|||
.int 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23 |
|||
.int 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 |
|||
tbConstH: .int 0x67452301 // H0 |
|||
.int 0xEFCDAB89 // H1 |
|||
.int 0x98BADCFE // H2 |
|||
.int 0x10325476 // H3 |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
.align 4 |
|||
sZoneConv: .skip 24 |
|||
tbH: .skip 4 * 4 @ 4 variables H |
|||
tbabcd: .skip 4 * 4 @ 4 variables a b c d |
|||
sZoneTrav: .skip 1000 |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: @ entry of program |
|||
ldr r0,iAdrszMessTest1 |
|||
bl computeExemple |
|||
ldr r0,iAdrszMessTest2 |
|||
bl computeExemple |
|||
ldr r0,iAdrszMessTest3 |
|||
bl computeExemple |
|||
ldr r0,iAdrszMessTest4 |
|||
bl computeExemple |
|||
ldr r0,iAdrszMessFinPgm |
|||
bl affichageMess @ display message |
|||
100: @ standard end of the program |
|||
mov r0, #0 @ return code |
|||
mov r7, #EXIT @ request to exit program |
|||
svc #0 @ perform the system call |
|||
iAdrszCarriageReturn: .int szCarriageReturn |
|||
iAdrszMessResult: .int szMessResult |
|||
iAdrszMessResult1: .int szMessResult1 |
|||
iAdrszMessTest1: .int szMessTest1 |
|||
iAdrszMessTest2: .int szMessTest2 |
|||
iAdrszMessTest3: .int szMessTest3 |
|||
iAdrszMessTest4: .int szMessTest4 |
|||
iAdrsZoneTrav: .int sZoneTrav |
|||
iAdrsZoneConv: .int sZoneConv |
|||
iAdrszMessFinPgm: .int szMessFinPgm |
|||
iAdrszMessSizeError: .int szMessSizeError |
|||
/***********************************************/ |
|||
/* compute exemple */ |
|||
/***********************************************/ |
|||
/* r0 contains the address of the message */ |
|||
computeExemple: |
|||
push {r1,lr} @ save registres |
|||
mov r1,r0 |
|||
bl computeMD5 @ call routine MD5 |
|||
ldr r0,iAdrszMessResult |
|||
bl affichageMess |
|||
mov r0,r1 |
|||
bl affichageMess |
|||
ldr r0,iAdrszMessResult1 |
|||
bl affichageMess |
|||
ldr r0, iAdrtbH |
|||
bl displayMD5 |
|||
100: |
|||
pop {r1,pc} @ restaur registers |
|||
/******************************************************************/ |
|||
/* compute MD5 */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the message */ |
|||
computeMD5: |
|||
push {r1-r12,lr} @ save registres |
|||
ldr r1,iAdrsZoneTrav |
|||
mov r2,#0 @ counter length |
|||
1: @ copy string in work area |
|||
cmp r2,#ZWORKSIZE @ maxi ? |
|||
bge 99f @ error |
|||
ldrb r3,[r0,r2] |
|||
strb r3,[r1,r2] |
|||
cmp r3,#0 |
|||
addne r2,r2,#1 |
|||
bne 1b |
|||
lsl r6,r2,#3 @ initial message length in bits |
|||
mov r3,#0b10000000 @ add bit 1 at end of string |
|||
strb r3,[r1,r2] |
|||
add r2,r2,#1 @ length in bytes |
|||
lsl r4,r2,#3 @ length in bits |
|||
mov r3,#0 |
|||
2: |
|||
lsr r5,r2,#6 |
|||
lsl r5,r5,#6 |
|||
sub r5,r2,r5 |
|||
cmp r5,#56 |
|||
beq 3f @ yes -> end add |
|||
strb r3,[r1,r2] @ add zero at message end |
|||
add r2,#1 @ increment lenght bytes |
|||
add r4,#8 @ increment length in bits |
|||
b 2b |
|||
3: |
|||
str r6,[r1,r2] @ and store length at end |
|||
add r5,r2,#4 |
|||
str r3,[r1,r5] @ store zero in hight bits for 64 bits |
|||
ldr r7,iAdrtbConstH @ constantes H address |
|||
ldr r4,iAdrtbH @ start area H |
|||
mov r5,#0 |
|||
4: @ init array H with start constantes |
|||
ldr r6,[r7,r5,lsl #2] @ load constante |
|||
str r6,[r4,r5,lsl #2] @ and store |
|||
add r5,r5,#1 |
|||
cmp r5,#4 |
|||
blt 4b |
|||
@ split into block of 64 bytes |
|||
add r2,#4 @ TODO : à revoir |
|||
lsr r4,r2,#6 @ blocks number |
|||
ldr r0,iAdrtbH @ variables H |
|||
ldr r1,iAdrsZoneTrav |
|||
ldr r5,iAdrtbConstK |
|||
ldr r3,iAdrtbRotaR |
|||
ldr r8,iAdrtbabcd |
|||
mov r7,#0 @ n° de block et r1 contient l adresse zone de travail |
|||
5: @ begin loop of each block of 64 bytes |
|||
add r2,r1,r7,lsl #6 @ compute block begin indice * 4 * 16 |
|||
mov r6,#0 @ indice t |
|||
/* COMPUTING THE MESSAGE DIGEST */ |
|||
/* r0 variables H address */ |
|||
/* r1 work area */ |
|||
/* r2 block work area begin address */ |
|||
/* r3 address constantes rotate */ |
|||
/* r4 block number */ |
|||
/* r5 constance K address */ |
|||
/* r6 counter t */ |
|||
/* r7 block counter */ |
|||
/* r8 addresse variables a b c d */ |
|||
@ init variable a b c d with variables H |
|||
mov r10,#0 |
|||
6: @ loop init |
|||
ldr r9,[r0,r10,lsl #2] @ variables H |
|||
str r9,[r8,r10,lsl #2] @ variables a b c d |
|||
add r10,r10,#1 |
|||
cmp r10,#4 |
|||
blt 6b |
|||
7: @ loop begin |
|||
cmp r6,#15 |
|||
bgt 8f |
|||
@ cas 1 f := (b et c) ou ((non b) et d) |
|||
@ g := i |
|||
ldr r9,[r8,#var_b] |
|||
ldr r10,[r8,#var_c] |
|||
and r12,r10,r9 |
|||
mvn r9,r9 |
|||
ldr r10,[r8,#var_d] |
|||
and r11,r9,r10 |
|||
orr r12,r12,r11 @ f |
|||
mov r9,r6 @ g |
|||
b 11f |
|||
8: |
|||
cmp r6,#31 |
|||
bgt 9f |
|||
@ f := (d et b) ou ((non d) et c) |
|||
@ g := (5×i + 1) mod 16 |
|||
ldr r9,[r8,#var_b] |
|||
ldr r10,[r8,#var_d] |
|||
and r12,r10,r9 |
|||
mvn r10,r10 |
|||
ldr r9,[r8,#var_c] |
|||
and r11,r9,r10 |
|||
orr r12,r12,r11 @ f |
|||
mov r9,#5 |
|||
mul r9,r6,r9 |
|||
add r9,r9,#1 |
|||
lsr r10,r9,#4 |
|||
lsl r10,r10,#4 |
|||
sub r9,r9,r10 @ g |
|||
b 11f |
|||
9: |
|||
cmp r6,#47 |
|||
bgt 10f |
|||
@ f := b xor c xor d |
|||
@ g := (3×i + 5) mod 16 |
|||
ldr r9,[r8,#var_b] |
|||
ldr r10,[r8,#var_c] |
|||
eor r12,r10,r9 |
|||
ldr r10,[r8,#var_d] |
|||
eor r12,r12,r10 @ f |
|||
mov r9,#3 |
|||
mul r9,r6,r9 |
|||
add r9,r9,#5 |
|||
lsr r10,r9,#4 |
|||
lsl r10,r10,#4 |
|||
sub r9,r9,r10 @ g |
|||
b 11f |
|||
10: |
|||
@ f := c xor (b ou (non d)) |
|||
@ g := (7×i) mod 16 |
|||
ldr r10,[r8,#var_d] |
|||
mvn r12,r10 |
|||
ldr r10,[r8,#var_b] |
|||
orr r12,r12,r10 |
|||
ldr r10,[r8,#var_c] |
|||
eor r12,r12,r10 @ f |
|||
mov r9,#7 |
|||
mul r9,r6,r9 |
|||
lsr r10,r9,#4 |
|||
lsl r10,r10,#4 |
|||
sub r9,r9,r10 @ g |
|||
11: |
|||
ldr r10,[r8,#var_d] |
|||
mov r11,r10 @ save old d |
|||
ldr r10,[r8,#var_c] |
|||
str r10,[r8,#var_d] @ new d = c |
|||
ldr r10,[r8,#var_b] |
|||
str r10,[r8,#var_c] @ new c = b |
|||
ldr r10,[r8,#var_a] |
|||
add r12,r12,r10 @ a + f |
|||
ldr r10,[r2,r9,lsl #2] |
|||
add r12,r12,r10 @ + valeur bloc g |
|||
ldr r10,[r5,r6,lsl #2] |
|||
add r12,r12,r10 @ + valeur constante K de i |
|||
ldr r10,[r3,r6,lsl #2] @ rotate left value |
|||
rsb r10,r10,#32 @ compute right rotate |
|||
ror r12,r12,r10 |
|||
ldr r10,[r8,#var_b] |
|||
add r12,r12,r10 |
|||
str r12,[r8,#var_b] @ new b |
|||
str r11,[r8,#var_a] @ new a = old d |
|||
add r6,r6,#1 |
|||
cmp r6,#63 |
|||
ble 7b |
|||
@ maj area H |
|||
ldr r10,[r0] @ H0 |
|||
ldr r11,[r8,#var_a] |
|||
add r10,r10,r11 @ + a |
|||
str r10,[r0] |
|||
ldr r10,[r0,#4] @ H1 |
|||
ldr r11,[r8,#var_b] |
|||
add r10,r10,r11 @ + b |
|||
str r10,[r0,#4] |
|||
ldr r10,[r0,#8] @ H2 |
|||
ldr r11,[r8,#var_c] |
|||
add r10,r10,r11 @ + c |
|||
str r10,[r0,#8] |
|||
ldr r10,[r0,#12] @ H3 |
|||
ldr r11,[r8,#var_d] |
|||
add r10,r10,r11 @ + d |
|||
str r10,[r0,#12] |
|||
@ loop other block |
|||
add r7,r7,#1 @ increment block |
|||
cmp r7,r4 @ maxi ? |
|||
ble 5b |
|||
mov r9,#0 @ reverse bytes loop |
|||
12: |
|||
ldr r10,[r0,r9,lsl #2] |
|||
rev r10,r10 @ reverse bytes |
|||
str r10,[r0,r9,lsl #2] |
|||
add r9,r9,#1 |
|||
cmp r9,#LGHASH / 4 |
|||
blt 12b |
|||
mov r0,#0 @ routine OK |
|||
b 100f |
|||
99: @ size error |
|||
ldr r0,iAdrszMessSizeError |
|||
bl affichageMess |
|||
mov r0,#-1 @ error routine |
|||
100: |
|||
pop {r1-r12,pc} @ restaur registers |
|||
iAdrtbConstH: .int tbConstH |
|||
iAdrtbConstK: .int tbConstK |
|||
iAdrtbRotaR: .int tbRotaR |
|||
iAdrtbH: .int tbH |
|||
iAdrtbabcd: .int tbabcd |
|||
/*************************************************/ |
|||
/* display hash MD5 */ |
|||
/*************************************************/ |
|||
/* r0 contains the address of hash */ |
|||
displayMD5: |
|||
push {r1-r3,lr} @ save registres |
|||
mov r3,r0 |
|||
mov r2,#0 |
|||
1: |
|||
ldr r0,[r3,r2,lsl #2] @ load 4 bytes |
|||
ldr r1,iAdrsZoneConv |
|||
bl conversion16 @ conversion hexa |
|||
ldr r0,iAdrsZoneConv |
|||
bl affichageMess |
|||
add r2,r2,#1 |
|||
cmp r2,#LGHASH / 4 |
|||
blt 1b @ and loop |
|||
ldr r0,iAdrszCarriageReturn |
|||
bl affichageMess @ display message |
|||
100: |
|||
pop {r1-r3,lr} @ restaur registers |
|||
bx lr @ return |
|||
/***************************************************/ |
|||
/* ROUTINES INCLUDE */ |
|||
/***************************************************/ |
|||
.include "../affichage.inc" |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Result for abc => 900150983CD24FB0D6963F7D28E17F72 |
|||
Result for ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 => D174AB98D277D9F5A5611C2C9F419D9F |
|||
Result for abcdefghijklmnopqrstuvwxyz => C3FCD3D76192E4007DFB496CCA67E13B |
|||
Result for 12345678901234567890123456789012345678901234567890123456789012345678901234567890 => 57EDF4A22BE3C955AC49DA2E2107B67A |
|||
Program End ok. |
|||
</pre> |
|||
=={{header|AutoHotkey}}== |
|||
{{AutoHotkey case}} |
{{AutoHotkey case}} |
||
===Regular version=== |
===Regular version=== |
||
Source: [http://www.autohotkey.com/forum/post-275910.html#275910 AutoHotkey forum] by SKAN |
Source: [http://www.autohotkey.com/forum/post-275910.html#275910 AutoHotkey forum] by SKAN |
||
<syntaxhighlight lang="autohotkey">data := "abc" |
|||
<br> |
|||
<lang autohotkey> |
|||
data := "abc" |
|||
MsgBox % MD5(data,StrLen(data)) ; 900150983cd24fb0d6963f7d28e17f72 |
MsgBox % MD5(data,StrLen(data)) ; 900150983cd24fb0d6963f7d28e17f72 |
||
Line 32: | Line 1,040: | ||
Return MD5 |
Return MD5 |
||
} |
} |
||
</syntaxhighlight> |
|||
} |
|||
</lang> |
|||
===Native implementation=== |
===Native implementation=== |
||
Source: [http://www.autohotkey.com/forum/topic17853.html AutoHotkey forum] by Laszlo |
Source: [http://www.autohotkey.com/forum/topic17853.html AutoHotkey forum] by Laszlo |
||
<syntaxhighlight lang="autohotkey">; GLOBAL CONSTANTS r[64], k[64] |
|||
<br> |
|||
<lang autohotkey> |
|||
; GLOBAL CONSTANTS r[64], k[64] |
|||
r = 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 |
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 |
, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20 |
||
Line 113: | Line 1,118: | ||
SetFormat Integer, DECIMAL |
SetFormat Integer, DECIMAL |
||
Return x |
Return x |
||
}</syntaxhighlight> |
|||
} |
|||
</lang> |
|||
=={{header|BaCon}}== |
|||
<syntaxhighlight lang="freebasic"> |
|||
PRAGMA INCLUDE <stdio.h> |
|||
PRAGMA INCLUDE <stdlib.h> |
|||
PRAGMA INCLUDE <string.h> |
|||
PRAGMA INCLUDE <openssl/md5.h> |
|||
PRAGMA LDFLAGS -lcrypto -lm -w |
|||
DECLARE result TYPE unsigned char * |
|||
DECLARE string TYPE const char * |
|||
string = "Rosetta code" |
|||
strlenght = LEN(string) |
|||
result = MD5( string, strlenght , 0) |
|||
FOR i = 0 TO MD5_DIGEST_LENGTH-1 |
|||
PRINT result[i] FORMAT "%02x" |
|||
NEXT</syntaxhighlight> |
|||
=={{header|BASIC256}}== |
|||
<syntaxhighlight lang="basic256">print MD5("") |
|||
print MD5("a") |
|||
print MD5("abc") |
|||
print MD5("message digest") |
|||
print MD5("abcdefghijklmnopqrstuvwxyz") |
|||
print MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") |
|||
print MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre>d41d8cd98f00b204e9800998ecf8427e |
|||
0cc175b9c0f1b6a831c399e269772661 |
|||
900150983cd24fb0d6963f7d28e17f72 |
|||
f96b697d7cb7938d525a2f31aaf161d0 |
|||
c3fcd3d76192e4007dfb496cca67e13b |
|||
d174ab98d277d9f5a5611c2c9f419d9f |
|||
57edf4a22be3c955ac49da2e2107b67a</pre> |
|||
=={{ |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
See [[MD5/Implementation]] for a native version. |
See [[MD5/Implementation]] for a native version. |
||
< |
<syntaxhighlight lang="bbcbasic"> PRINT FN_MD5("") |
||
PRINT FN_MD5("a") |
PRINT FN_MD5("a") |
||
PRINT FN_MD5("abc") |
PRINT FN_MD5("abc") |
||
Line 137: | Line 1,181: | ||
MD5$ += RIGHT$("0"+STR$~(MD5_CTX.digest&(I%)),2) |
MD5$ += RIGHT$("0"+STR$~(MD5_CTX.digest&(I%)),2) |
||
NEXT |
NEXT |
||
= MD5$</ |
= MD5$</syntaxhighlight> |
||
=={{header|C}}== |
=={{header|C}}== |
||
{{libheader|OpenSSL}} |
{{libheader|OpenSSL}} |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
Line 161: | Line 1,205: | ||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</ |
}</syntaxhighlight> |
||
Implementation of md5 |
Implementation of md5 |
||
(Needs review - differences observed for the last 8 characters when compared with openssl implementation) |
|||
<lang c>#include <stdlib.h> |
|||
<syntaxhighlight lang="c">#include <stdlib.h> |
|||
#include <stdio.h> |
#include <stdio.h> |
||
#include <string.h> |
#include <string.h> |
||
Line 282: | Line 1,327: | ||
os += 64; |
os += 64; |
||
} |
} |
||
if( msg2 ) |
|||
free( msg2 ); |
|||
return h; |
return h; |
||
} |
} |
||
Line 300: | Line 1,349: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
<syntaxhighlight lang="csharp">using System.Text; |
|||
<lang csharp>using System.Text; |
|||
using System.Security.Cryptography; |
using System.Security.Cryptography; |
||
byte[] data = Encoding.ASCII.GetBytes("The quick brown fox jumped over the lazy dog's back"); |
byte[] data = Encoding.ASCII.GetBytes("The quick brown fox jumped over the lazy dog's back"); |
||
byte[] hash = MD5.Create().ComputeHash(data); |
byte[] hash = MD5.Create().ComputeHash(data); |
||
Console.WriteLine(BitConverter.ToString(hash).Replace("-", "").ToLower());</ |
Console.WriteLine(BitConverter.ToString(hash).Replace("-", "").ToLower());</syntaxhighlight> |
||
=={{header| |
=={{header|C++}}== |
||
{{libheader| |
{{libheader|Poco Crypto}} |
||
<syntaxhighlight lang="cpp">#include <string> |
|||
<lang d>module md5test ; |
|||
#include <iostream> |
|||
import tango.io.digest.Md5 ; |
|||
#include "Poco/MD5Engine.h" |
|||
import tango.io.Stdout ; |
|||
#include "Poco/DigestStream.h" |
|||
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: |
|||
<pre>>md5test "The quick brown fox jumped over the lazy dog's back" |
|||
[The quick brown fox jumped over the lazy dog's back]=> |
|||
[e38ca1d920c4b8b8d3946b2c72f01680]</pre> |
|||
using Poco::DigestEngine ; |
|||
=={{header|Clojure}}== |
|||
using Poco::MD5Engine ; |
|||
using Poco::DigestOutputStream ; |
|||
int main( ) { |
|||
<lang lisp> |
|||
std::string myphrase ( "The quick brown fox jumped over the lazy dog's back" ) ; |
|||
(apply str |
|||
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 ; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>The quick brown fox jumped over the lazy dog's back as a MD5 digest : |
|||
e38ca1d920c4b8b8d3946b2c72f01680 ! |
|||
</pre> |
|||
=={{header|Caché ObjectScript}}== |
|||
<pre>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</pre> |
|||
=={{header|Clojure}}== |
|||
<syntaxhighlight lang="lisp">(apply str |
|||
(map (partial format "%02x") |
(map (partial format "%02x") |
||
(.digest (doto (java.security.MessageDigest/getInstance "MD5") |
(.digest (doto (java.security.MessageDigest/getInstance "MD5") |
||
.reset |
.reset |
||
(.update (.getBytes "The quick brown fox jumps over the lazy dog")))))) |
(.update (.getBytes "The quick brown fox jumps over the lazy dog"))))))</syntaxhighlight> |
||
</lang> |
|||
=={{header|COBOL}}== |
|||
<syntaxhighlight lang="cobol"> |
|||
IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. MD5. |
|||
AUTHOR. Bill Gunshannon |
|||
INSTALLATION. Home. |
|||
DATE-WRITTEN. 16 December 2021. |
|||
************************************************************ |
|||
** Program Abstract: |
|||
** Use the md5sum utility and pass the HASH back using |
|||
** a temp file. Not elegant, but it works. |
|||
************************************************************ |
|||
ENVIRONMENT DIVISION. |
|||
INPUT-OUTPUT SECTION. |
|||
FILE-CONTROL. |
|||
SELECT Tmp-MD5 ASSIGN TO "/tmp/MD5" |
|||
ORGANIZATION IS LINE SEQUENTIAL. |
|||
DATA DIVISION. |
|||
FILE SECTION. |
|||
FD Tmp-MD5 |
|||
DATA RECORD IS MD5-Rec. |
|||
01 MD5-Rec PIC X(32). |
|||
WORKING-STORAGE SECTION. |
|||
01 Eof PIC X VALUE 'F'. |
|||
01 Str1. |
|||
05 Pre-cmd PIC X(8) |
|||
VALUE 'echo -n '. |
|||
05 Str1-complete. |
|||
10 Str1-Part1 PIC X(26) |
|||
VALUE 'The quick brown fox jumps'. |
|||
10 Str1-Part2 PIC X(19) |
|||
VALUE ' over the lazy dog'. |
|||
05 Post-cmd PIC X(20) |
|||
VALUE ' | md5sum > /tmp/MD5'. |
|||
01 Str1-MD5 PIC X(32). |
|||
PROCEDURE DIVISION. |
|||
Main-Program. |
|||
DISPLAY Str1-complete. |
|||
PERFORM Get-MD5. |
|||
DISPLAY Str1-MD5. |
|||
STOP RUN. |
|||
Get-MD5. |
|||
CALL "SYSTEM" USING Str1. |
|||
OPEN INPUT Tmp-MD5. |
|||
READ Tmp-MD5 INTO Str1-MD5. |
|||
CLOSE Tmp-MD5. |
|||
CALL "CBL_DELETE_FILE" USING '/tmp/MD5'. |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="cobol"> |
|||
IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. MD5-DEMO. |
|||
AUTHOR. Bill Gunshannon |
|||
INSTALLATION. Home. |
|||
DATE-WRITTEN. 16 December 2021. |
|||
************************************************************ |
|||
** Program Abstract: |
|||
** Use the md5sum utility and pass the HASH back using |
|||
** a temp file. Not elegant, but it works. |
|||
** Same program but made MD5 a User Defined Function |
|||
** instead of a procedure. |
|||
************************************************************ |
|||
ENVIRONMENT DIVISION. |
|||
CONFIGURATION SECTION. |
|||
REPOSITORY. |
|||
FUNCTION MD5. |
|||
DATA DIVISION. |
|||
WORKING-STORAGE SECTION. |
|||
01 Eof PIC X VALUE 'F'. |
|||
01 Str1. |
|||
05 Pre-cmd PIC X(8) |
|||
VALUE 'echo -n '. |
|||
05 Str1-complete. |
|||
10 Str1-Part1 PIC X(26) |
|||
VALUE 'The quick brown fox jumps'. |
|||
10 Str1-Part2 PIC X(19) |
|||
VALUE ' over the lazy dog'. |
|||
05 Post-cmd PIC X(20) |
|||
VALUE ' | md5sum > /tmp/MD5'. |
|||
01 Str1-MD5 PIC X(32). |
|||
PROCEDURE DIVISION. |
|||
Main-Program. |
|||
DISPLAY Str1-complete. |
|||
* PERFORM Get-MD5. |
|||
MOVE FUNCTION MD5(Str1) TO Str1-MD5. |
|||
DISPLAY Str1-MD5. |
|||
STOP RUN. |
|||
END PROGRAM MD5-DEMO. |
|||
IDENTIFICATION DIVISION. |
|||
FUNCTION-ID. MD5. |
|||
ENVIRONMENT DIVISION. |
|||
INPUT-OUTPUT SECTION. |
|||
FILE-CONTROL. |
|||
SELECT Tmp-MD5 ASSIGN TO "/tmp/MD5" |
|||
ORGANIZATION IS LINE SEQUENTIAL. |
|||
DATA DIVISION. |
|||
FILE SECTION. |
|||
FD Tmp-MD5 |
|||
DATA RECORD IS MD5-Rec. |
|||
01 MD5-Rec PIC X(32). |
|||
LINKAGE SECTION. |
|||
01 Str1 PIC X(128). |
|||
01 Str1-MD5 PIC X(32). |
|||
PROCEDURE DIVISION USING Str1 RETURNING Str1-MD5. |
|||
CALL "SYSTEM" USING FUNCTION TRIM(Str1). |
|||
OPEN INPUT Tmp-MD5. |
|||
READ Tmp-MD5 INTO Str1-MD5. |
|||
CLOSE Tmp-MD5. |
|||
CALL "CBL_DELETE_FILE" USING '/tmp/MD5'. |
|||
GO-BACK. |
|||
END FUNCTION MD5. |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
The quick brown fox jumps over the lazy dog |
|||
9e107d9d372bb6826bd81d3542a419d6 |
|||
</pre> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
{{libheader|Ironclad}} |
|||
<syntaxhighlight 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))) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
This one uses a library, but if you want to see how it's implemented, press M-x slime-edit-definition and go to <tt>md5:md5sum-stream</tt>. |
|||
<pre>"": d41d8cd98f00b204e9800998ecf8427e |
|||
"a": 0cc175b9c0f1b6a831c399e269772661 |
|||
"abc": 900150983cd24fb0d6963f7d28e17f72 |
|||
"message digest": f96b697d7cb7938d525a2f31aaf161d0 |
|||
"abcdefghijklmnopqrstuvwxyz": c3fcd3d76192e4007dfb496cca67e13b |
|||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": d174ab98d277d9f5a5611c2c9f419d9f |
|||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890": 57edf4a22be3c955ac49da2e2107b67a</pre> |
|||
<h5>Another method using openssl:</h5> {{libheader|CFFI}} |
|||
<lang lisp>(require #+sbcl 'sb-md5 #-sbcl 'md5) |
|||
<syntaxhighlight lang="lisp">(cffi:load-foreign-library "libcrypto.so") |
|||
(cffi:defcfun ("MD5" MD5) :void (string :string) (len :int) (ptr :pointer)) |
|||
(defvar +letters+ "0123456789abcdef") |
|||
(let ((string-to-convert "The quick brown fox jumped over the lazy dog's back") |
|||
(defun octets->letters (octet-vector) |
|||
(ptr (cffi:foreign-alloc :unsigned-char :count 16))) |
|||
(with-output-to-string (stream) |
|||
(md5 string-to-convert (length string-to-convert) ptr) |
|||
(loop for i across octet-vector |
|||
(loop for i from 0 below 16 do |
|||
do (flet ((foo (x) (aref +letters+ (ldb (byte x (- x 4)) i)))) |
|||
(format t "~a" (write-to-string (cffi:mem-ref ptr :unsigned-char i) :base 16))) |
|||
(princ (foo 8) stream) |
|||
(cffi:foreign-free ptr))</syntaxhighlight> |
|||
(princ (foo 4) stream))))) |
|||
{{Out}}<pre>E38CA1D920C4B8B8D3946B2C72F01680</pre> |
|||
(defun md5 (string) |
|||
(octets->letters #+sbcl (sb-md5:md5sum-string string) |
|||
#-sbcl (with-input-from-string (stream string) |
|||
(md5:md5sum-stream stream))))</pre> |
|||
=={{header|Crystal}}== |
|||
CL-USER> (md5 "foo") |
|||
<syntaxhighlight lang="ruby">require "digest/md5" |
|||
"acbd18db4cc2f85cedef654fccc4a4d8"</lang> |
|||
puts Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back")</syntaxhighlight> |
|||
=={{header|E}}== |
|||
{{Out}}<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
=={{header|D}}== |
|||
{{works with|E-on-Java}} |
|||
<syntaxhighlight lang="d">void main() { |
|||
import std.stdio, std.digest.md; |
|||
auto txt = "The quick brown fox jumped over the lazy dog's back"; |
|||
{{trans|Java}} (with modifications) |
|||
writefln("%-(%02x%)", txt.md5Of); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
Alternative version: |
|||
{{libheader|Tango}} |
|||
<syntaxhighlight lang="d">import tango.io.digest.Md5, tango.io.Stdout; |
|||
void main(char[][] args) { |
|||
<lang e>def makeMessageDigest := <import:java.security.makeMessageDigest> |
|||
auto md5 = new Md5(); |
|||
for(int i = 1; i < args.length; i++) { |
|||
md5.update(args[i]); |
|||
Stdout.formatln("[{}]=>\n[{}]", args[i], md5.hexDigest()); |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>>md5test "The quick brown fox jumped over the lazy dog's back" |
|||
[The quick brown fox jumped over the lazy dog's back]=> |
|||
[e38ca1d920c4b8b8d3946b2c72f01680]</pre> |
|||
=={{header|Delphi}}== |
|||
If you require a native implementation, look inside the class '''TIdHashMessageDigest5'''. This class is placed in the unit '''IdHashMessageDigest.pas'''. |
|||
<syntaxhighlight 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.</syntaxhighlight> |
|||
'''Output:''' |
|||
<pre> |
|||
D41D8CD98F00B204E9800998ECF8427E |
|||
0CC175B9C0F1B6A831C399E269772661 |
|||
900150983CD24FB0D6963F7D28E17F72 |
|||
F96B697D7CB7938D525A2F31AAF161D0 |
|||
C3FCD3D76192E4007DFB496CCA67E13B |
|||
D174AB98D277D9F5A5611C2C9F419D9F |
|||
57EDF4A22BE3C955AC49DA2E2107B67A |
|||
</pre> |
|||
=={{header|E}}== |
|||
{{works with|E-on-Java}} |
|||
{{trans|Java}} (with modifications) |
|||
<syntaxhighlight lang="e">def makeMessageDigest := <import:java.security.makeMessageDigest> |
|||
def sprintf := <import:java.lang.makeString>.format |
def sprintf := <import:java.lang.makeString>.format |
||
Line 376: | Line 1,684: | ||
print(sprintf("%02x", [b])) |
print(sprintf("%02x", [b])) |
||
} |
} |
||
println()</ |
println()</syntaxhighlight> |
||
=={{header|EasyLang}}== |
|||
<syntaxhighlight lang=text> |
|||
len md5k[] 64 |
|||
proc md5init . . |
|||
for i = 1 to 64 |
|||
md5k[i] = floor (0x100000000 * abs sin (i * 180 / pi)) |
|||
. |
|||
. |
|||
md5init |
|||
# |
|||
func$ md5 inp$ . |
|||
subr addinp |
|||
if inp4 = 1 |
|||
inp[] &= 0 |
|||
. |
|||
inp[len inp[]] += b * inp4 |
|||
inp4 *= 0x100 |
|||
if inp4 = 0x100000000 |
|||
inp4 = 1 |
|||
. |
|||
. |
|||
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 ] |
|||
inp[] = [ ] |
|||
inp4 = 1 |
|||
for i = 1 to len inp$ |
|||
b = strcode substr inp$ i 1 |
|||
addinp |
|||
. |
|||
b = 0x80 |
|||
addinp |
|||
while len inp[] mod 16 <> 14 or inp4 <> 1 |
|||
b = 0 |
|||
addinp |
|||
. |
|||
h = len inp$ * 8 |
|||
for i = 1 to 4 |
|||
b = h mod 0x100 |
|||
addinp |
|||
h = h div 0x100 |
|||
. |
|||
inp[] &= 0 |
|||
# |
|||
a0 = 0x67452301 |
|||
b0 = 0xefcdab89 |
|||
c0 = 0x98badcfe |
|||
d0 = 0x10325476 |
|||
for chunk = 1 step 16 to len inp[] - 15 |
|||
a = a0 ; b = b0 ; c = c0 ; d = d0 |
|||
for i = 1 to 64 |
|||
if i <= 16 |
|||
h1 = bitand b c |
|||
h2 = bitand bitnot b d |
|||
f = bitor h1 h2 |
|||
g = i - 1 |
|||
elif i <= 32 |
|||
h1 = bitand d b |
|||
h2 = bitand bitnot d c |
|||
f = bitor h1 h2 |
|||
g = (5 * i - 4) mod 16 |
|||
elif i <= 48 |
|||
h1 = bitxor b c |
|||
f = bitxor h1 d |
|||
g = (3 * i + 2) mod 16 |
|||
else |
|||
h1 = bitor b bitnot d |
|||
f = bitxor c h1 |
|||
g = (7 * i - 7) mod 16 |
|||
. |
|||
f = (f + a + md5k[i] + inp[chunk + g]) |
|||
a = d |
|||
d = c |
|||
c = b |
|||
h1 = bitshift f s[i] |
|||
h2 = bitshift f (s[i] - 32) |
|||
b = (b + h1 + h2) |
|||
. |
|||
a0 += a ; b0 += b ; c0 += c ; d0 += d |
|||
. |
|||
for a in [ a0 b0 c0 d0 ] |
|||
for i = 1 to 4 |
|||
b = a mod 256 |
|||
a = a div 256 |
|||
for h in [ b div 16 b mod 16 ] |
|||
h += 48 |
|||
if h > 57 |
|||
h += 39 |
|||
. |
|||
s$ &= strchar h |
|||
. |
|||
. |
|||
. |
|||
return s$ |
|||
. |
|||
# |
|||
print md5 "The quick brown fox jumped over the lazy dog's back" |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</pre> |
|||
=={{header|Emacs Lisp}}== |
|||
<syntaxhighlight lang="lisp">(md5 "The quick brown fox jumped over the lazy dog's back") ;=> "e38ca1d920c4b8b8d3946b2c72f01680" |
|||
(secure-hash 'md5 "The quick brown fox jumped over the lazy dog's back") ;=> "e38ca1d920c4b8b8d3946b2c72f01680"</syntaxhighlight> |
|||
=={{header|Erlang}}== |
=={{header|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: |
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: |
||
<syntaxhighlight lang="erlang">-module(tests). |
|||
<lang Erlang> |
|||
-module(tests). |
|||
-export([md5/1]). |
-export([md5/1]). |
||
Line 387: | Line 1,800: | ||
string:to_upper( |
string:to_upper( |
||
lists:flatten([io_lib:format("~2.16.0b",[N]) || <<N>> <= erlang:md5(S)]) |
lists:flatten([io_lib:format("~2.16.0b",[N]) || <<N>> <= erlang:md5(S)]) |
||
).</syntaxhighlight> |
|||
). |
|||
</lang> |
|||
Testing it: |
Testing it: |
||
< |
<syntaxhighlight lang="erlang">1> c(tests). |
||
1> c(tests). |
|||
{ok,tests} |
{ok,tests} |
||
2> tests:md5("The quick brown fox jumped over the lazy dog's back"). |
2> tests:md5("The quick brown fox jumped over the lazy dog's back"). |
||
"E38CA1D920C4B8B8D3946B2C72F01680" |
"E38CA1D920C4B8B8D3946B2C72F01680"</syntaxhighlight> |
||
</lang> |
|||
=={{header|F_Sharp|F#}}== |
|||
Using built-in System.Security.Cryptography.MD5 class (Link to original blog [https://znprojects.blogspot.com/2017/04/md5-in-f-functionally.html]). |
|||
<syntaxhighlight lang="f#">let md5ootb (msg: string) = |
|||
use md5 = System.Security.Cryptography.MD5.Create() |
|||
msg |
|||
|> System.Text.Encoding.ASCII.GetBytes |
|||
|> md5.ComputeHash |
|||
|> Seq.map (fun c -> c.ToString("X2")) |
|||
|> Seq.reduce ( + ) |
|||
md5ootb @"The quick brown fox jumped over the lazy dog's back"</syntaxhighlight> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Line 407: | Line 1,829: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
{{libheader|Forth Foundation Library}} |
{{libheader|Forth Foundation Library}} |
||
<syntaxhighlight lang="forth">include ffl/md5.fs |
|||
\ Create a MD5 variable md1 in the dictionary |
|||
md5-create md1 |
|||
\ Create a MD5 variable md1 in the dictionary |
|||
\ Update the variable with data |
|||
md5-create md1 |
|||
s" The quick brown fox jumps over the lazy dog" md1 md5-update |
|||
\ Update the variable with data |
|||
\ Finish the MD5 calculation resulting in four unsigned 32 bit words |
|||
s" The quick brown fox jumps over the lazy dog" md1 md5-update |
|||
\ on the stack representing the hash value |
|||
md1 md5-finish |
|||
\ Finish the MD5 calculation resulting in four unsigned 32 bit words |
|||
\ on the stack representing the hash value |
|||
\ Convert the hash value to a hex string and print it |
|||
md1 md5-finish |
|||
md5+to-string type cr</syntaxhighlight> |
|||
\ Convert the hash value to a hex string and print it |
|||
=={{header|Fortran}}== |
|||
===Intel Fortran on Windows=== |
|||
Using Windows API. See [https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta CryptAcquireContextA], [https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcreatehash CryptCreateHash], [https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashdata CryptHashData] and [https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgethashparam CryptGetHashParam] in Microsoft documentation. |
|||
<syntaxhighlight lang="fortran">module md5_mod |
|||
use kernel32 |
|||
use advapi32 |
|||
implicit none |
|||
integer, parameter :: MD5LEN = 16 |
|||
contains |
|||
subroutine md5hash(name, hash, dwStatus, filesize) |
|||
implicit none |
|||
character(*) :: name |
|||
integer, parameter :: BUFLEN = 32768 |
|||
integer(HANDLE) :: hFile, hProv, hHash |
|||
integer(DWORD) :: dwStatus, nRead |
|||
integer(BOOL) :: status |
|||
integer(BYTE) :: buffer(BUFLEN) |
|||
integer(BYTE) :: hash(MD5LEN) |
|||
integer(UINT64) :: filesize |
|||
dwStatus = 0 |
|||
md5+to-string type cr |
|||
filesize = 0 |
|||
hFile = CreateFile(trim(name) // char(0), GENERIC_READ, FILE_SHARE_READ, NULL, & |
|||
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) |
|||
if (hFile == INVALID_HANDLE_VALUE) then |
|||
dwStatus = GetLastError() |
|||
print *, "CreateFile failed." |
|||
return |
|||
end if |
|||
if (CryptAcquireContext(hProv, NULL, NULL, PROV_RSA_FULL, & |
|||
CRYPT_VERIFYCONTEXT) == FALSE) then |
|||
dwStatus = GetLastError() |
|||
print *, "CryptAcquireContext failed." |
|||
goto 3 |
|||
end if |
|||
if (CryptCreateHash(hProv, CALG_MD5, 0_ULONG_PTR, 0_DWORD, hHash) == FALSE) then |
|||
dwStatus = GetLastError() |
|||
print *, "CryptCreateHash failed." |
|||
go to 2 |
|||
end if |
|||
do |
|||
status = ReadFile(hFile, loc(buffer), BUFLEN, nRead, NULL) |
|||
if (status == FALSE .or. nRead == 0) exit |
|||
filesize = filesize + nRead |
|||
if (CryptHashData(hHash, buffer, nRead, 0) == FALSE) then |
|||
dwStatus = GetLastError() |
|||
print *, "CryptHashData failed." |
|||
go to 1 |
|||
end if |
|||
end do |
|||
if (status == FALSE) then |
|||
dwStatus = GetLastError() |
|||
print *, "ReadFile failed." |
|||
go to 1 |
|||
end if |
|||
nRead = MD5LEN |
|||
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, nRead, 0) == FALSE) then |
|||
dwStatus = GetLastError() |
|||
print *, "CryptGetHashParam failed.", status, nRead, dwStatus |
|||
end if |
|||
1 status = CryptDestroyHash(hHash) |
|||
2 status = CryptReleaseContext(hProv, 0) |
|||
3 status = CloseHandle(hFile) |
|||
end subroutine |
|||
end module |
|||
program md5 |
|||
use md5_mod |
|||
implicit none |
|||
integer :: n, m, i, j |
|||
character(:), allocatable :: name |
|||
integer(DWORD) :: dwStatus |
|||
integer(BYTE) :: hash(MD5LEN) |
|||
integer(UINT64) :: filesize |
|||
n = command_argument_count() |
|||
do i = 1, n |
|||
call get_command_argument(i, length=m) |
|||
allocate(character(m) :: name) |
|||
call get_command_argument(i, name) |
|||
call md5hash(name, hash, dwStatus, filesize) |
|||
if (dwStatus == 0) then |
|||
do j = 1, MD5LEN |
|||
write(*, "(Z2.2)", advance="NO") hash(j) |
|||
end do |
|||
write(*, "(' ',A,' (',G0,' bytes)')") name, filesize |
|||
end if |
|||
deallocate(name) |
|||
end do |
|||
end program</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
|||
See [[MD5/Implementation#FreeBASIC]] |
|||
=={{header|Frink}}== |
=={{header|Frink}}== |
||
The <CODE>messageDigest[string, hash]</CODE> returns a hex-encoded hash of any input string with a variety of hashing functions. |
The function <CODE>messageDigest[string, hash]</CODE> returns a hex-encoded hash of any input string with a variety of hashing functions. |
||
<syntaxhighlight lang="frink">println[messageDigest["The quick brown fox", "MD5"]]</syntaxhighlight> |
|||
<lang frink> |
|||
println[messageDigest["The quick brown fox", "MD5"]] |
|||
=={{header|Futhark}}== |
|||
</lang> |
|||
Real languages roll their own crypto. |
|||
<syntaxhighlight lang="futhark"> |
|||
type md5 = (u32, u32, u32, u32) |
|||
fun rs(): [64]u32 = |
|||
map u32 |
|||
([ 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 ]) |
|||
fun ks(): [64]u32 = |
|||
map u32 |
|||
([ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee , |
|||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 , |
|||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be , |
|||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 , |
|||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa , |
|||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 , |
|||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed , |
|||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a , |
|||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c , |
|||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 , |
|||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 , |
|||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 , |
|||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 , |
|||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 , |
|||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 , |
|||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 ]) |
|||
fun md5(ms: [n][16]u32): md5 = |
|||
let a0 = u32(0x67452301) |
|||
let b0 = u32(0xefcdab89) |
|||
let c0 = u32(0x98badcfe) |
|||
let d0 = u32(0x10325476) |
|||
loop ((a0,b0,c0,d0)) = for i < n do |
|||
let (a,b,c,d) = md5_chunk (a0,b0,c0,d0) ms[i] |
|||
in (a0+a, b0+b, c0+c, d0+d) |
|||
in (a0,b0,c0,d0) |
|||
fun rotate_left(x: u32, c: u32): u32 = (x << c) | (x >> (32u32 - c)) |
|||
fun bytes(x: u32): [4]u8 = [u8(x), |
|||
u8(x/0x100u32), |
|||
u8(x/0x10000u32), |
|||
u8(x/0x1000000u32)] |
|||
fun unbytes(bs: [4]u8): u32 = |
|||
u32(bs[0]) + |
|||
u32(bs[1]) * 0x100u32 + |
|||
u32(bs[2]) * 0x10000u32 + |
|||
u32(bs[3]) * 0x1000000u32 |
|||
fun unbytes_block(block: [64]u8): [16]u32 = |
|||
map unbytes (reshape (16,4) block) |
|||
fun main(ms: [n]u8): [16]u8 = |
|||
let padding = 64 - (n % 64) |
|||
let n_padded = n + padding |
|||
let ms_padded = concat ms (bytes 0x80u32) (replicate (padding-12) 0x0u8) (bytes (u32(n*8))) ([0u8,0u8,0u8,0u8]) |
|||
let (a,b,c,d) = md5 (map unbytes_block (reshape (n_padded / 64, 64) ms_padded)) |
|||
in reshape 16 (map bytes ([a,b,c,d])) |
|||
-- Process 512 bits of the input. |
|||
fun md5_chunk ((a0,b0,c0,d0): md5) (m: [16]u32): md5 = |
|||
loop ((a,b,c,d) = (a0,b0,c0,d0)) = for i < 64 do |
|||
let (f,g) = |
|||
if i < 16 then ((b & c) | ((~b) & d), |
|||
i) |
|||
else if i < 32 then ((d & b) | ((~d) & c), |
|||
i32((5u32*u32(i) + 1u32) % 16u32)) |
|||
else if i < 48 then (b ^ c ^ d, |
|||
i32((3u32*u32(i) + 5u32) % 16u32)) |
|||
else (c ^ (b | (~d)), |
|||
i32((7u32*u32(i)) % 16u32)) |
|||
in (d, b + rotate_left(a + f + (ks())[i] + m[g], (rs())[i]), b, c) |
|||
in (a,b,c,d) |
|||
</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 448: | Line 2,052: | ||
{"f96b697d7cb7938d525a2f31aaf161d0", "message digest"}, |
{"f96b697d7cb7938d525a2f31aaf161d0", "message digest"}, |
||
{"c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"}, |
{"c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"}, |
||
{"d174ab98d277d9f5a5611c2c9f419d9f" |
{"d174ab98d277d9f5a5611c2c9f419d9f", |
||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, |
|||
{"57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, |
|||
{"57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890" + |
|||
"123456789012345678901234567890123456789012345678901234567890"}, |
|||
// test case popular with other RC solutions |
// test case popular with other RC solutions |
||
{"e38ca1d920c4b8b8d3946b2c72f01680" |
{"e38ca1d920c4b8b8d3946b2c72f01680", |
||
"The quick brown fox jumped over the lazy dog's back"}, |
|||
} { |
} { |
||
validate(p[0], p[1]) |
validate(p[0], p[1]) |
||
Line 462: | Line 2,069: | ||
h.Reset() |
h.Reset() |
||
h.Write([]byte(s)) |
h.Write([]byte(s)) |
||
sum := fmt.Sprintf("%x", h.Sum()) |
sum := fmt.Sprintf("%x", h.Sum(nil)) |
||
if sum != check { |
if sum != check { |
||
fmt.Println("MD5 fail") |
fmt.Println("MD5 fail") |
||
Line 469: | Line 2,076: | ||
fmt.Println(" got: ", sum) |
fmt.Println(" got: ", sum) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Groovy}}== |
|||
<syntaxhighlight lang="groovy">import java.security.MessageDigest |
|||
String.metaClass.md5Checksum = { |
|||
MessageDigest.getInstance('md5').digest(delegate.bytes).collect { String.format("%02x", it) }.join('') |
|||
}</syntaxhighlight> |
|||
Testing |
|||
<syntaxhighlight lang="groovy">assert 'The quick brown fox jumps over the lazy dog'.md5Checksum() == '9e107d9d372bb6826bd81d3542a419d6'</syntaxhighlight> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Use modules nano-MD5 and ByteString from [http://hackage.haskell.org/packages/hackage.html HackageDB] |
Use modules nano-MD5 and ByteString from [http://hackage.haskell.org/packages/hackage.html HackageDB] |
||
<lang |
<syntaxhighlight lang="haskell">import Data.Digest.OpenSSL.MD5 (md5sum) |
||
import Data.ByteString (pack) |
|||
import Data.Char (ord) |
|||
main = do |
main = do |
||
let message = "The quick brown fox jumped over the lazy dog's back" |
|||
putStrLn $ md5sum $ pack |
|||
digest = (md5sum . pack . map (fromIntegral . ord)) message |
|||
$ map (fromIntegral.ord) "The quick brown fox jumped over the lazy dog's back"</lang> |
|||
putStrLn digest</syntaxhighlight> |
|||
Use in GHCi: |
Use in GHCi: |
||
<pre>*Main> main |
<pre>*Main> main |
||
e38ca1d920c4b8b8d3946b2c72f01680</pre> |
e38ca1d920c4b8b8d3946b2c72f01680</pre> |
||
This version uses the [https://hackage.haskell.org/package/cryptonite Cryptonite] package: |
|||
=={{header|Io}}== |
|||
{{libheader|Cryptonite}} |
|||
<lang io>Io> MD5 |
|||
<syntaxhighlight lang="haskell">#!/usr/bin/env runhaskell |
|||
==> MD5_0x97663e0: |
|||
appendSeq = MD5_appendSeq() |
|||
import Data.ByteString.Char8 (pack) |
|||
md5 = MD5_md5() |
|||
import System.Environment (getArgs) |
|||
md5String = MD5_md5String() |
|||
import Crypto.Hash |
|||
Io> MD5 clone appendSeq("The quick brown fox jumped over the lazy dog's back") md5String |
|||
==> e38ca1d920c4b8b8d3946b2c72f01680</lang> |
|||
main :: IO () |
|||
main = print . md5 . pack . unwords =<< getArgs |
|||
where md5 x = hash x :: Digest MD5</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ ./md5.hs The quick brown fox jumped over the lazy dog\'s back |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</pre> |
|||
=={{header|Haxe}}== |
|||
<syntaxhighlight lang="haxe">import haxe.crypto.Md5; |
|||
class Main { |
|||
static function main() { |
|||
var md5 = Md5.encode("The quick brown fox jumped over the lazy dog's back"); |
|||
Sys.println(md5); |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|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. |
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. |
||
< |
<syntaxhighlight 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", 16r9e107d9d372bb6826bd81d3542a419d6) |
||
testMD5("The quick brown fox jumps over the lazy dog.", 16re4d909c290d0fb1ca068ffaddf22cbd0) |
testMD5("The quick brown fox jumps over the lazy dog.", 16re4d909c290d0fb1ca068ffaddf22cbd0) |
||
Line 502: | Line 2,143: | ||
write("Message(length=",*s,") = ",image(s)) |
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") |
write("Digest = ",hexstring(h := MD5(s)),if h = rh then " matches reference hash" else (" does not match reference hash = " || hexstring(rh)),"\n") |
||
end</ |
end</syntaxhighlight> |
||
Sample Output:<pre>Message(length=43) = "The quick brown fox jumps over the lazy dog" |
Sample Output:<pre>Message(length=43) = "The quick brown fox jumps over the lazy dog" |
||
Line 512: | Line 2,153: | ||
Message(length=0) = "" |
Message(length=0) = "" |
||
Digest = D41D8CD98F00B204E9800998ECF8427E matches reference hash</pre> |
Digest = D41D8CD98F00B204E9800998ECF8427E matches reference hash</pre> |
||
=={{header|Io}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Using the <tt>[ |
Using the <tt>[https://github.com/jsoftware/convert_misc/blob/master/md5.ijs md5]</tt> script from the <tt>convert/misc</tt> addon package: |
||
<syntaxhighlight lang="j"> require 'convert/misc/md5' |
|||
<lang j> |
|||
require 'convert/misc/md5' |
|||
md5 'The quick brown fox jumped over the lazy dog''s back' |
md5 'The quick brown fox jumped over the lazy dog''s back' |
||
e38ca1d920c4b8b8d3946b2c72f01680 |
e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
||
</lang> |
|||
Implementation here, in case the link to the script goes dead again: |
|||
=={{header|Java}}== |
|||
<syntaxhighlight lang="j">require 'convert' |
|||
'`lt gt ge xor'=: (20 b.)`(18 b.)`(27 b.)`(22 b.) |
|||
Modified from [http://mindprod.com/jgloss/md5.html mindprod's Java Glossary]: |
|||
'`and or sh'=: (17 b.)`(23 b.)`(33 b.) |
|||
<lang java>import java.io.UnsupportedEncodingException; |
|||
{{ |
|||
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=: {{ |
|||
'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{{)n |
|||
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{{)n |
|||
_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=: {{ |
|||
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 |
|||
}} |
|||
md5=: {{ |
|||
X=. norm y |
|||
q=. r=. 1732584193 _271733879 _1732584194 271733878 |
|||
for_k. X do. |
|||
for_j. i.4 do. |
|||
l=. ((j{I){k) ,. (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 |
|||
}}</syntaxhighlight> |
|||
An alternative and faster approach is to use the Qt library function available using the <tt>ide/qt</tt> addon from J8: |
|||
<syntaxhighlight lang="j"> require '~addons/ide/qt/qt.ijs' |
|||
getmd5=: 'md5'&gethash_jqtide_ |
|||
getmd5 'The quick brown fox jumped over the lazy dog''s back' |
|||
e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
|||
=={{header|Java}}== |
|||
<syntaxhighlight lang="java">import java.nio.charset.StandardCharsets; |
|||
import java.security.MessageDigest; |
import java.security.MessageDigest; |
||
import java.security.NoSuchAlgorithmException; |
import java.security.NoSuchAlgorithmException; |
||
public class Digester { |
|||
/** |
|||
* 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(); |
|||
public static void main(String[] args) { |
|||
// dump out the hash |
|||
System.out.println(hexDigest("Rosetta code", "MD5")); |
|||
for(byte b: digest){ |
|||
} |
|||
System.out.printf("%02X", b & 0xff); |
|||
} |
|||
static String hexDigest(String str, String digestName) { |
|||
System.out.println(); |
|||
try { |
|||
} |
|||
MessageDigest md = MessageDigest.getInstance(digestName); |
|||
}</lang> |
|||
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8)); |
|||
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. |
|||
char[] hex = new char[digest.length * 2]; |
|||
for (int i = 0; i < digest.length; i++) { |
|||
hex[2 * i] = "0123456789abcdef".charAt((digest[i] & 0xf0) >> 4); |
|||
hex[2 * i + 1] = "0123456789abcdef".charAt(digest[i] & 0x0f); |
|||
} |
|||
return new String(hex); |
|||
} catch (NoSuchAlgorithmException e) { |
|||
throw new IllegalStateException(e); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
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 "UTF_8" in the example above) are available from the Charset and StandardCharsets classes. |
|||
=={{header|Jsish}}== |
|||
<syntaxhighlight lang="javascript">/* MD5 hash in Jsish */ |
|||
var str = 'Rosetta code'; |
|||
puts(Util.hash(str, {type:'md5'})); |
|||
/* MD5 RFC1321 test suite */ |
|||
function MD5(str) { return Util.hash(str, {type:'md5'}); } |
|||
;MD5(''); |
|||
;MD5('a'); |
|||
;MD5('abc'); |
|||
;MD5('message digest'); |
|||
;MD5('abcdefghijklmnopqrstuvwxyz'); |
|||
;MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'); |
|||
;MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'); |
|||
/* |
|||
=!EXPECTSTART!= |
|||
bf0ac9c7e94e9d50c18f4ff592643546 |
|||
MD5('') ==> d41d8cd98f00b204e9800998ecf8427e |
|||
MD5('a') ==> 0cc175b9c0f1b6a831c399e269772661 |
|||
MD5('abc') ==> 900150983cd24fb0d6963f7d28e17f72 |
|||
MD5('message digest') ==> f96b697d7cb7938d525a2f31aaf161d0 |
|||
MD5('abcdefghijklmnopqrstuvwxyz') ==> c3fcd3d76192e4007dfb496cca67e13b |
|||
MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') ==> d174ab98d277d9f5a5611c2c9f419d9f |
|||
MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') ==> 57edf4a22be3c955ac49da2e2107b67a |
|||
=!EXPECTEND!= |
|||
*/</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ jsish md5.jsi |
|||
bf0ac9c7e94e9d50c18f4ff592643546 |
|||
prompt$ jsish --U md5.jsi # display unit test echos |
|||
bf0ac9c7e94e9d50c18f4ff592643546 |
|||
MD5('') ==> d41d8cd98f00b204e9800998ecf8427e |
|||
MD5('a') ==> 0cc175b9c0f1b6a831c399e269772661 |
|||
MD5('abc') ==> 900150983cd24fb0d6963f7d28e17f72 |
|||
MD5('message digest') ==> f96b697d7cb7938d525a2f31aaf161d0 |
|||
MD5('abcdefghijklmnopqrstuvwxyz') ==> c3fcd3d76192e4007dfb496cca67e13b |
|||
MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') ==> d174ab98d277d9f5a5611c2c9f419d9f |
|||
MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') ==> 57edf4a22be3c955ac49da2e2107b67a |
|||
prompt$ jsish -u md5.jsi # run the unit tests |
|||
[PASS] md5.jsi</pre> |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|0.6}} |
|||
<syntaxhighlight lang="julia">using Nettle |
|||
function Base.trunc(s::AbstractString, n::Integer) |
|||
n > 0 || throw(DomainError()) |
|||
l = length(s) |
|||
l > n || return s |
|||
n > 3 || 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, h) in sort(tests, by = length ∘ first) |
|||
md5sum = hexdigest("md5", k) |
|||
@printf("%20s → %s ", trunc(k, 15), md5sum) |
|||
if md5sum == h |
|||
println("MD5 OK") |
|||
else |
|||
println("MD5 Bad") |
|||
println("* The sum should be ", h) |
|||
end |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre> → 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 O</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.0.6 |
|||
import java.security.MessageDigest |
|||
fun main(args: Array<String>) { |
|||
val text = "The quick brown fox jumped over the lazy dog's back" |
|||
val bytes = text.toByteArray() |
|||
val md = MessageDigest.getInstance("MD5") |
|||
val digest = md.digest(bytes) |
|||
for (byte in digest) print("%02x".format(byte)) |
|||
println() |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</pre> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso">Encrypt_MD5('Welcome all Rhinos!') |
|||
//80ba88ee2600e9e9b36e739458c39ebd</syntaxhighlight> |
|||
===Test suite=== |
|||
<syntaxhighlight 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' |
|||
^}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>testing: "12345678901234567890123456789012345678901234567890123456789012345678901234567890": true |
|||
testing: "a": true |
|||
testing: "abc": true |
|||
testing: "abcdefghijklmnopqrstuvwxyz": true |
|||
testing: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": true |
|||
testing: "message digest": true</pre> |
|||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
< |
<syntaxhighlight lang="lb">'[RC]MD5 |
||
'from tsh73's January 2008 code |
'from tsh73's January 2008 code |
||
Line 670: | Line 2,540: | ||
end function |
end function |
||
Line 700: | Line 2,569: | ||
a$=left$("00000000", 8-len(a$))+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)) |
revOrd$ = lower$(mid$(a$,7,2)+mid$(a$,5,2)+mid$(a$,3,2)+mid$(a$,1,2)) |
||
end function</ |
end function</syntaxhighlight> |
||
=={{header| |
=={{header|Lingo}}== |
||
*Using a binary plugin ("Xtra"): |
|||
Using the [http://www.keplerproject.org/md5/ Kepler MD5 library]: |
|||
{{libheader|Crypto Xtra}} |
|||
<syntaxhighlight lang="lingo">put cx_md5_string(str)</syntaxhighlight> |
|||
*Pure Lingo implementation |
|||
<lang Lua>require "md5" |
|||
<syntaxhighlight lang="lingo">---------------------------------------- |
|||
-- Calculates MD5 hash of string or bytearray |
|||
-- @param {bytearray|string} input |
|||
-- @return {bytearray} (16 bytes) |
|||
---------------------------------------- |
|||
on md5 (input) |
|||
if stringP(input) then input = bytearray(input) |
|||
-- Convert string to list of little-endian words... |
|||
t_iLen = input.length * 8 |
|||
t_iCnt = (t_iLen + 64) / 512 * 16 + 16 |
|||
-- Create list, fill with zeros... |
|||
x = [] |
|||
x[t_iCnt] = 0 |
|||
t_fArr = [1, 256, 65536, 16777216] |
|||
i = 0 |
|||
j = 0 |
|||
repeat while i < t_iLen |
|||
j = j + 1 |
|||
t_iNext = i / 32 + 1 |
|||
t_iTemp = bitAnd(input[i/8+1], 255) * t_fArr[j] |
|||
x[t_iNext] = bitOr(x[t_iNext], t_iTemp) |
|||
i = i + 8 |
|||
j = j mod 4 |
|||
end repeat |
|||
-- Append padding... |
|||
t_iNext = t_iLen / 32 + 1 |
|||
x[t_iNext] = bitOr(x[t_iNext], 128 * t_fArr[j + 1]) |
|||
x[(t_iLen + 64) / 512 * 16 + 15] = t_iLen |
|||
-- Actual algorithm starts here... |
|||
a = 1732584193 |
|||
b = -271733879 |
|||
c = -1732584194 |
|||
d = 271733878 |
|||
i = 1 |
|||
t_iWrap = the maxInteger + 1 |
|||
t_iCount = x.count + 1 |
|||
repeat while i < t_iCount |
|||
olda = a |
|||
oldb = b |
|||
oldc = c |
|||
oldd = d |
|||
-- Round(1) -- |
|||
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i] - 680876936 |
|||
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b |
|||
else a = bitOr(n * 128, n / 33554432) + b |
|||
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 1] - 389564586 |
|||
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a |
|||
else d = bitOr(n * 4096, n / 1048576) + a |
|||
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 2] + 606105819 |
|||
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d |
|||
else c = bitOr(n * 131072, n / 32768) + d |
|||
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 3] - 1044525330 |
|||
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c |
|||
else b = bitOr(n * 4194304, n / 1024) + c |
|||
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 4] - 176418897 |
|||
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b |
|||
else a = bitOr(n * 128, n / 33554432) + b |
|||
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 5] + 1200080426 |
|||
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a |
|||
else d = bitOr(n * 4096, n / 1048576) + a |
|||
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 6] - 1473231341 |
|||
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d |
|||
else c = bitOr(n * 131072, n / 32768) + d |
|||
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 7] - 45705983 |
|||
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c |
|||
else b = bitOr(n * 4194304, n / 1024) + c |
|||
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 8] + 1770035416 |
|||
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b |
|||
else a = bitOr(n * 128, n / 33554432) + b |
|||
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 9] - 1958414417 |
|||
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a |
|||
else d = bitOr(n * 4096, n / 1048576) + a |
|||
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 10] - 42063 |
|||
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d |
|||
else c = bitOr(n * 131072, n / 32768) + d |
|||
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 11] - 1990404162 |
|||
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c |
|||
else b = bitOr(n * 4194304, n / 1024) + c |
|||
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 12] + 1804603682 |
|||
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b |
|||
else a = bitOr(n * 128, n / 33554432) + b |
|||
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 13] - 40341101 |
|||
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a |
|||
else d = bitOr(n * 4096, n / 1048576) + a |
|||
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 14] - 1502002290 |
|||
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d |
|||
else c = bitOr(n * 131072, n / 32768) + d |
|||
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 15] + 1236535329 |
|||
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c |
|||
else b = bitOr(n * 4194304, n / 1024) + c |
|||
-- Round(2) -- |
|||
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 1] - 165796510 |
|||
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b |
|||
else a = bitOr(n * 32, n / 134217728) + b |
|||
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 6] - 1069501632 |
|||
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a |
|||
else d = bitOr(n * 512, n / 8388608) + a |
|||
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 11] + 643717713 |
|||
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d |
|||
else c = bitOr(n * 16384, n / 262144) + d |
|||
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i] - 373897302 |
|||
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c |
|||
else b = bitOr(n * 1048576, n / 4096) + c |
|||
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 5] - 701558691 |
|||
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b |
|||
else a = bitOr(n * 32, n / 134217728) + b |
|||
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 10] + 38016083 |
|||
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a |
|||
else d = bitOr(n * 512, n / 8388608) + a |
|||
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 15] - 660478335 |
|||
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d |
|||
else c = bitOr(n * 16384, n / 262144) + d |
|||
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 4] - 405537848 |
|||
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c |
|||
else b = bitOr(n * 1048576, n / 4096) + c |
|||
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 9] + 568446438 |
|||
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b |
|||
else a = bitOr(n * 32, n / 134217728) + b |
|||
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 14] - 1019803690 |
|||
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a |
|||
else d = bitOr(n * 512, n / 8388608) + a |
|||
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 3] - 187363961 |
|||
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d |
|||
else c = bitOr(n * 16384, n / 262144) + d |
|||
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 8] + 1163531501 |
|||
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c |
|||
else b = bitOr(n * 1048576, n / 4096) + c |
|||
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 13] - 1444681467 |
|||
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b |
|||
else a = bitOr(n * 32, n / 134217728) + b |
|||
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 2] - 51403784 |
|||
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a |
|||
else d = bitOr(n * 512, n / 8388608) + a |
|||
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 7] + 1735328473 |
|||
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d |
|||
else c = bitOr(n * 16384, n / 262144) + d |
|||
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 12] - 1926607734 |
|||
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c |
|||
else b = bitOr(n * 1048576, n / 4096) + c |
|||
-- Round(3) -- |
|||
n = bitXor(bitXor(b, c), d) + a + x[i + 5] - 378558 |
|||
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b |
|||
else a = bitOr(n * 16, n / 268435456) + b |
|||
n = bitXor(bitXor(a, b), c) + d + x[i + 8] - 2022574463 |
|||
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a |
|||
else d = bitOr(n * 2048, n / 2097152) + a |
|||
n = bitXor(bitXor(d, a), b) + c + x[i + 11] + 1839030562 |
|||
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d |
|||
else c = bitOr(n * 65536, n / 65536) + d |
|||
n = bitXor(bitXor(c, d), a) + b + x[i + 14] - 35309556 |
|||
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c |
|||
else b = bitOr(n * 8388608, n / 512) + c |
|||
n = bitXor(bitXor(b, c), d) + a + x[i + 1] - 1530992060 |
|||
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b |
|||
else a = bitOr(n * 16, n / 268435456) + b |
|||
n = bitXor(bitXor(a, b), c) + d + x[i + 4] + 1272893353 |
|||
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a |
|||
else d = bitOr(n * 2048, n / 2097152) + a |
|||
n = bitXor(bitXor(d, a), b) + c + x[i + 7] - 155497632 |
|||
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d |
|||
else c = bitOr(n * 65536, n / 65536) + d |
|||
n = bitXor(bitXor(c, d), a) + b + x[i + 10] - 1094730640 |
|||
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c |
|||
else b = bitOr(n * 8388608, n / 512) + c |
|||
n = bitXor(bitXor(b, c), d) + a + x[i + 13] + 681279174 |
|||
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b |
|||
else a = bitOr(n * 16, n / 268435456) + b |
|||
n = bitXor(bitXor(a, b), c) + d + x[i] - 358537222 |
|||
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a |
|||
else d = bitOr(n * 2048, n / 2097152) + a |
|||
n = bitXor(bitXor(d, a), b) + c + x[i + 3] - 722521979 |
|||
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d |
|||
else c = bitOr(n * 65536, n / 65536) + d |
|||
n = bitXor(bitXor(c, d), a) + b + x[i + 6] + 76029189 |
|||
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c |
|||
else b = bitOr(n * 8388608, n / 512) + c |
|||
n = bitXor(bitXor(b, c), d) + a + x[i + 9] - 640364487 |
|||
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b |
|||
else a = bitOr(n * 16, n / 268435456) + b |
|||
n = bitXor(bitXor(a, b), c) + d + x[i + 12] - 421815835 |
|||
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a |
|||
else d = bitOr(n * 2048, n / 2097152) + a |
|||
n = bitXor(bitXor(d, a), b) + c + x[i + 15] + 530742520 |
|||
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d |
|||
else c = bitOr(n * 65536, n / 65536) + d |
|||
n = bitXor(bitXor(c, d), a) + b + x[i + 2] - 995338651 |
|||
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c |
|||
else b = bitOr(n * 8388608, n / 512) + c |
|||
-- Round(4) -- |
|||
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i] - 198630844 |
|||
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b |
|||
else a = bitOr(n * 64, n / 67108864) + b |
|||
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 7] + 1126891415 |
|||
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a |
|||
else d = bitOr(n * 1024, n / 4194304) + a |
|||
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 14] - 1416354905 |
|||
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d |
|||
else c = bitOr(n * 32768, n / 131072) + d |
|||
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 5] - 57434055 |
|||
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c |
|||
else b = bitOr(n * 2097152, n / 2048) + c |
|||
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 12] + 1700485571 |
|||
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b |
|||
else a = bitOr(n * 64, n / 67108864) + b |
|||
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 3] - 1894986606 |
|||
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a |
|||
else d = bitOr(n * 1024, n / 4194304) + a |
|||
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 10] - 1051523 |
|||
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d |
|||
else c = bitOr(n * 32768, n / 131072) + d |
|||
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 1] - 2054922799 |
|||
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c |
|||
else b = bitOr(n * 2097152, n / 2048) + c |
|||
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 8] + 1873313359 |
|||
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b |
|||
else a = bitOr(n * 64, n / 67108864) + b |
|||
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 15] - 30611744 |
|||
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a |
|||
else d = bitOr(n * 1024, n / 4194304) + a |
|||
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 6] - 1560198380 |
|||
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d |
|||
else c = bitOr(n * 32768, n / 131072) + d |
|||
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 13] + 1309151649 |
|||
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c |
|||
else b = bitOr(n * 2097152, n / 2048) + c |
|||
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 4] - 145523070 |
|||
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b |
|||
else a = bitOr(n * 64, n / 67108864) + b |
|||
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 11] - 1120210379 |
|||
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a |
|||
else d = bitOr(n * 1024, n / 4194304) + a |
|||
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 2] + 718787259 |
|||
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d |
|||
else c = bitOr(n * 32768, n / 131072) + d |
|||
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 9] - 343485551 |
|||
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c |
|||
else b = bitOr(n * 2097152, n / 2048) + c |
|||
a = a + olda |
|||
b = b + oldb |
|||
c = c + oldc |
|||
d = d + oldd |
|||
i = i + 16 |
|||
end repeat |
|||
t_iArr = [a, b, c, d] |
|||
ba = bytearray() |
|||
p = 1 |
|||
repeat with i in t_iArr |
|||
if(i > 0) then |
|||
repeat with n = 1 to 4 |
|||
ba[p] = (i mod 256) |
|||
i = i / 256 |
|||
p = p+1 |
|||
end repeat |
|||
else |
|||
i = bitNot(i) |
|||
repeat with n = 1 to 4 |
|||
ba[p] = 255-(i mod 256) |
|||
i = i / 256 |
|||
p = p+1 |
|||
end repeat |
|||
end if |
|||
end repeat |
|||
ba.position = 1 |
|||
return ba |
|||
end</syntaxhighlight> |
|||
=={{header|LiveCode}}== |
|||
Livecode has built-in support for md4 and md5 |
|||
<syntaxhighlight lang="livecode">function md5sum hashtext |
|||
local md5, mdhex |
|||
put md5Digest(hashtext) into md5 |
|||
get binaryDecode("H*",md5,mdhex) |
|||
return mdhex |
|||
end md5sum</syntaxhighlight> |
|||
Tests<syntaxhighlight 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</syntaxhighlight> |
|||
Output |
|||
<pre>ok abc |
|||
ok abclower |
|||
ok 123 |
|||
ok abcupper |
|||
ok message digest |
|||
ok a |
|||
ok empty</pre> |
|||
=={{header|Lua}}== |
|||
Using the [http://www.keplerproject.org/md5/ Kepler MD5 library]: |
|||
<syntaxhighlight lang="lua">require "md5" |
|||
--printing a sum: |
--printing a sum: |
||
Line 721: | Line 2,914: | ||
test("abcdefghijklmnopqrstuvwxyz","c3fcd3d76192e4007dfb496cca67e13b") |
test("abcdefghijklmnopqrstuvwxyz","c3fcd3d76192e4007dfb496cca67e13b") |
||
test("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789","d174ab98d277d9f5a5611c2c9f419d9f") |
test("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789","d174ab98d277d9f5a5611c2c9f419d9f") |
||
test("12345678901234567890123456789012345678901234567890123456789012345678901234567890","57edf4a22be3c955ac49da2e2107b67a") |
test("12345678901234567890123456789012345678901234567890123456789012345678901234567890","57edf4a22be3c955ac49da2e2107b67a")</syntaxhighlight> |
||
</lang> |
|||
=={{header| |
=={{header|Maple}}== |
||
The <tt>Hash</tt> command in the <tt>StringTools</tt> package computes the MD5 hash value of a string. |
|||
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: |
|||
<syntaxhighlight lang="maple"> |
|||
<lang Mathematica> |
|||
> with( StringTools ): |
|||
StringHash[string_String]:=Module[{stream=OpenWrite[],file,hash}, |
|||
> Hash( "" ); |
|||
WriteString[stream,string]; |
|||
"d41d8cd98f00b204e9800998ecf8427e" |
|||
file=Close[stream]; |
|||
hash=FileHash[file,"MD5"]; |
|||
> Hash( "a" ); |
|||
DeleteFile[file]; |
|||
"0cc175b9c0f1b6a831c399e269772661" |
|||
hash |
|||
] |
|||
> Hash( "abc" ); |
|||
</lang> |
|||
"900150983cd24fb0d6963f7d28e17f72" |
|||
> Hash( "message digest" ); |
|||
"f96b697d7cb7938d525a2f31aaf161d0" |
|||
> Hash( "abcdefghijklmnopqrstuvwxyz" ); |
|||
"c3fcd3d76192e4007dfb496cca67e13b" |
|||
> Hash( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ); |
|||
"d174ab98d277d9f5a5611c2c9f419d9f" |
|||
> Hash( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" ); |
|||
"57edf4a22be3c955ac49da2e2107b67a" |
|||
</syntaxhighlight> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
Mathematica has built-in functions Hash and FileHash. |
|||
Example: |
Example: |
||
<syntaxhighlight lang="mathematica"> Hash["The quick brown fox jumped over the lazy dog's back","MD5","HexString"]</syntaxhighlight> |
|||
<lang Mathematica> |
|||
StringHash["The quick brown fox jumped over the lazy dog's back"] // BaseForm[#, 16] & |
|||
</lang> |
|||
gives back: |
gives back: |
||
<syntaxhighlight lang="mathematica"> e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
|||
<lang Mathematica> |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</lang> |
|||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
This code also works with Octave (but Octave already provides md5sum(), see [[{{FULLPAGENAME}}#Octave|Octave example]]). |
|||
{{improve|MATLAB|The sample implementation doesn't return the correct hashes}} |
|||
A fast implementation can be found here: [http://www.mathworks.com/matlabcentral/fileexchange/8944-compute-hash-using-md2-md5-sha-1-sha-256-sha-384-or-sha-512 MATLAB Central]. The file to which I have linked uses MATLAB's Java language interface to use the MD5 algorithm built into Java's compiler libraries. |
|||
<syntaxhighlight lang="matlab">function digest = md5(message) |
|||
A MATLAB implementation is below. It is an almost direct translation of the pseudo-code given in the MD5 wikipedia entry. Unfortunately, there is something wrong with this implementation. It does not return the correct hash of the input. I think it has something to do with the endianness of some of the variables. Despite that, this is a decent example of how this algorithm might be implemented. This implementation requires [http://www.mathworks.com/matlabcentral/fileexchange/1975-bin2hex this] file in order to run. |
|||
% 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]. |
|||
<lang MATLAB>function digest = md5(message) |
|||
% [1] http://tools.ietf.org/html/rfc1321 |
|||
% [2] http://en.wikipedia.org/wiki/MD5 |
|||
% m is the modulus for 32-bit unsigned arithmetic. |
|||
%% Helper Function Definitions |
|||
m = 2 ^ 32; |
|||
% s is the shift table for circshift(). Each shift is negative |
|||
%This function converts a binary representation of a number or vector |
|||
% because it is a left shift. |
|||
%of numbers from a string to a row vector of 1's and 0's |
|||
s = [-7, -12, -17, -22 |
|||
function matrix = binStr2mat(binStr) |
|||
-5, -9, -14, -20 |
|||
-4, -11, -16, -23 |
|||
-6, -10, -15, -21]; |
|||
end |
|||
end |
|||
% t is the sine table. Each sine is a 32-bit integer, unsigned. |
|||
%This acts as a "lower <= x <= upper" operator |
|||
t = floor(abs(sin(1:64)) .* m); |
|||
function trueFalse = inRange(lowerBound,theValue,upperBound) |
|||
trueFalse = (lowerBound <= theValue) && (theValue <= upperBound); |
|||
end |
|||
% |
% Initialize the hash, as a row vector of 32-bit integers. |
||
digest = [hex2dec('67452301') ... |
|||
%and I'm pretty sure it is little-endian |
|||
hex2dec('EFCDAB89') ... |
|||
function binaryRep = to32BitBin(decimal) |
|||
hex2dec('98BADCFE') ... |
|||
hex2dec('10325476')]; |
|||
end |
|||
% If message contains characters, convert them to ASCII values. |
|||
%This converts a decimal number into its 64-bit binary representation, |
|||
message = double(message); |
|||
%and I'm pretty sure it is little-endian |
|||
bytelen = numel(message); |
|||
function binaryRep = to64BitBin(decimal) |
|||
binaryRep = binStr2mat(dec2bin(decimal,64)); |
|||
end |
|||
% Pad the message by appending a 1, then appending enough 0s to make |
|||
%This adds multiple binary numbers together modulo 2^32. The sum of these |
|||
% the bit length congruent to 448 mod 512. Because we have bytes, we |
|||
%numbers will rap around if the sum of two numbers is >= 2^32 |
|||
% append 128 '10000000', then append enough 0s '00000000's to make |
|||
function result = addBinary(varargin) |
|||
% the byte length congruent to 56 mod 64. |
|||
message = [message, 128, zeros(1, mod(55 - bytelen, 64))]; |
|||
for l = (1:numel(varargin)) |
|||
temp = num2str(varargin{l}); |
|||
temp(temp == ' ') = []; |
|||
result = mod(result + bin2dec(temp),2^32); |
|||
end |
|||
result = to32BitBin(result); |
|||
end |
|||
% Convert the message to 32-bit integers, little endian. |
|||
%% MD5 Hash Algorithm |
|||
% For little endian, first byte is least significant byte. |
|||
message = reshape(message, 4, numel(message) / 4); |
|||
%Define constants |
|||
message = message(1,:) + ... % least significant byte |
|||
%r is the bit-shift amount for each round |
|||
message(2,:) * 256 + ... |
|||
r =[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,... |
|||
message(3,:) * 65536 + ... |
|||
9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,... |
|||
message(4,:) * 16777216; % most significant byte |
|||
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21]; |
|||
%Use the binary representation of the radian values of sine represented |
|||
%as 32-bit integers |
|||
k = to32BitBin(floor(abs(sin(1:64)).*(2^32))); |
|||
% Append the bit length as a 64-bit integer, little endian. |
|||
%Initialize the hash variables, convert the hex representation of these |
|||
bitlen = bytelen * 8; |
|||
%variables to their 32-bit binary representation |
|||
message = [message, mod(bitlen, m), mod(bitlen / m, m)]; |
|||
h0 = to32BitBin(hex2dec('67452301')); |
|||
h1 = to32BitBin(hex2dec('EFCDAB89')); |
|||
h2 = to32BitBin(hex2dec('98BADCFE')); |
|||
h3 = to32BitBin(hex2dec('10325476')); |
|||
% Process each 512-bit block. Because we have 32-bit integers, each |
|||
%Convert the ASCII values of the input string to a binary string matrix |
|||
message |
% 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); |
|||
%Convert the message matrix to one long bit stream |
|||
message = reshape(transpose(message),1,N); |
|||
% Do 64 operations. |
|||
%Perform the pre-prossesing of appending a 1-bit to the message, then |
|||
%enough zeros to make the length of the message congruent to 448 mod |
|||
%512. Then append the 64-bit representation of the length of the |
|||
%original message string to the end. |
|||
message = [binStr2mat([message '1']) zeros(1,abs(mod(N+1,512) - 448)) to64BitBin(N)]; |
|||
%Process 512-bit chunks of the pre-processed message string |
|||
for chunk = (1:(numel(message)/512)) |
|||
%Stored the index of the first bit in the chunk |
|||
blockIndex = ((chunk-1)*512)+1; |
|||
%Pull out the 512-bit chunk from the message, then reshape it into |
|||
%32, 16-bit strings. Then transpose that string matrix to recover 16, |
|||
%32-bit words in the correct order. If we do this directly, by |
|||
%reshaping the 512-bit chunk to 16, 32-bit strings the original |
|||
%order of the bits will be scrambled. |
|||
w = transpose(reshape(message(blockIndex:blockIndex+511),32,16)); |
|||
%Initialize the hashes for this round |
|||
a = h0; |
|||
b = h1; |
|||
c = h2; |
|||
d = h3; |
|||
%Process the hahes |
|||
%Note: The original MD5 algorithm pseudo-code was written for |
|||
%0-based arrays. Therefore, the calculation for "g" has been |
|||
%modified for MATLAB's 1-based arrays |
|||
for i = (1:64) |
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'; |
|||
f = (d & b) | ((~d) & c); |
|||
% 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 |
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; |
temp = d; |
||
d = c; |
d = c; |
||
c = b; |
c = b; |
||
b = mod(b + sum, m); |
|||
%The circshift has a -r(i) because normally this function |
|||
%rotates right, not left. |
|||
b = addBinary(b,circshift( addBinary(a,f,k(i,1:32),w(g,1:32)),[0 -r(i)] )); |
|||
a = temp; |
a = temp; |
||
end %for i |
|||
end |
|||
% Add hash of this block to hash of previous blocks. |
|||
digest = mod(digest + [a, b, c, d], m); |
|||
end %for k |
|||
h0 = addBinary(h0,a); |
|||
h1 = addBinary(h1,b); |
|||
% Convert hash from 32-bit integers, little endian, to bytes. |
|||
h2 = addBinary(h2,c); |
|||
digest = [digest % least significant byte |
|||
h3 = addBinary(h3,d); |
|||
digest / 256 |
|||
digest / 65536 |
|||
end |
|||
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</syntaxhighlight> |
|||
Sample Usage: |
|||
<syntaxhighlight lang="matlab">octave:14> md5('Rosetta Code') |
|||
ans = CCA1BF66B09554E10F837838C3D3EFB1</syntaxhighlight> |
|||
=={{header|min}}== |
|||
{{works with|min|0.19.6}} |
|||
<syntaxhighlight lang="min">"The quick brown fox jumps over the lazy dog" md5 puts!</syntaxhighlight> |
|||
=={{header|MOO}}== |
|||
<syntaxhighlight lang="moo">string = "The quick brown fox jumped over the lazy dog's back"; |
|||
player:tell(string_hash(string));</syntaxhighlight> |
|||
=={{header|Neko}}== |
|||
<syntaxhighlight lang="actionscript">/** |
|||
MD5 in Neko |
|||
Tectonics: |
|||
nekoc md5.neko |
|||
neko md5 |
|||
*/ |
|||
var MD5 = $loader.loadprim("std@make_md5", 1); |
|||
var base_encode = $loader.loadprim("std@base_encode", 2); |
|||
var result = MD5("The quick brown fox jumps over the lazy dog"); |
|||
/* Output in lowercase hex */ |
|||
$print(base_encode(result, "0123456789abcdef"));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ nekoc md5.neko |
|||
prompt$ neko md5.n |
|||
9e107d9d372bb6826bd81d3542a419d6</pre> |
|||
=={{header|Nemerle}}== |
|||
{{trans|C#}} |
|||
<syntaxhighlight 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 |
|||
%Concatenate the hashes together and convert them to a binary string |
|||
{ |
|||
digest = num2str([h0 h1 h2 h3]); |
|||
HashMD5(text) == hash.ToLower() |
|||
} |
|||
Main() : void |
|||
%Remove whitespace from the digest, leaving 1's and 0's |
|||
{ |
|||
digest(digest == ' ') = []; |
|||
def examples = ["The quick brown fox jumped over the lazy dog's back", "", "a", "abc", "message digest", |
|||
"abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", |
|||
%Convert the binary representation of the digest to a hexadecimal |
|||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"]; |
|||
digest = lower(bin2hex(digest)); |
|||
def hashes = ["e38ca1d920c4b8b8d3946b2c72f01680", "d41d8cd98f00b204e9800998ecf8427e", |
|||
"0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", |
|||
end %md5</lang> |
|||
"f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", |
|||
"d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a"]; |
|||
def tests = Hashtable(ZipLazy(examples, hashes)); |
|||
foreach (test in tests) |
|||
Write($"$(IsValidMD5(test.Key, test.Value)) "); |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>True True True True True True True True</pre> |
|||
=={{header|NetRexx}}== |
|||
Sample Usage: |
|||
<syntaxhighlight lang="netrexx">/* NetRexx */ |
|||
<lang MATLAB>>> md5('The quick brown fox jumps over the lazy dog.') |
|||
options replace format comments java crossref savelog symbols binary |
|||
ans = |
|||
import java.security.MessageDigest |
|||
c8cc939f167a20b55ddfe18c1b7f23f7 %This is not the correct hash</lang> |
|||
MD5('The quick brown fox jumps over the lazy dog', '9e107d9d372bb6826bd81d3542a419d6') |
|||
=={{header|MOO}}== |
|||
-- RFC 1321 MD5 test suite: |
|||
<lang moo>string = "The quick brown fox jumped over the lazy dog's back"; |
|||
MD5("", 'd41d8cd98f00b204e9800998ecf8427e') |
|||
player:tell(string_hash(string));</lang> |
|||
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 |
|||
</syntaxhighlight> |
|||
'''Output:''' |
|||
<pre> |
|||
<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 |
|||
</pre> |
|||
=={{header|NewLISP}}== |
|||
<syntaxhighlight 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")</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="nim">import md5 |
|||
echo toMD5("The quick brown fox jumped over the lazy dog's back")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
=={{header|Nu}}== |
|||
<syntaxhighlight lang="nu">[ |
|||
'' 'a' 'abc' 'message digest' |
|||
'abcdefghijklmnopqrstuvwxyz' |
|||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' |
|||
'12345678901234567890123456789012345678901234567890123456789012345678901234567890' |
|||
] |
|||
| each { hash md5 }</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
╭───┬──────────────────────────────────╮ |
|||
│ 0 │ d41d8cd98f00b204e9800998ecf8427e │ |
|||
│ 1 │ 0cc175b9c0f1b6a831c399e269772661 │ |
|||
│ 2 │ 900150983cd24fb0d6963f7d28e17f72 │ |
|||
│ 3 │ f96b697d7cb7938d525a2f31aaf161d0 │ |
|||
│ 4 │ c3fcd3d76192e4007dfb496cca67e13b │ |
|||
│ 5 │ d174ab98d277d9f5a5611c2c9f419d9f │ |
|||
│ 6 │ 57edf4a22be3c955ac49da2e2107b67a │ |
|||
╰───┴──────────────────────────────────╯ |
|||
</pre> |
|||
=={{header|Oberon-2}}== |
|||
{{works with|oo2c}}{{libheader|crypto}} |
|||
<syntaxhighlight 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. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
MD5: |
|||
E38CA1D9 20C4B8B8 D3946B2C 72F01680 |
|||
</pre> |
|||
=={{header|Objeck}}== |
|||
<syntaxhighlight 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(); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
{{works with|GNUstep}} only; not Cocoa |
{{works with|GNUstep}} only; not Cocoa |
||
< |
<syntaxhighlight 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 |
NSData *digest = [[myString dataUsingEncoding:NSUTF8StringEncoding] md5Digest]; // or another encoding of your choosing |
||
NSLog(@"%@", [digest hexadecimalRepresentation]);</ |
NSLog(@"%@", [digest hexadecimalRepresentation]);</syntaxhighlight> |
||
{{works with|iPhone}} |
{{works with|iPhone}} |
||
{{works with|Mac OS X}} |
{{works with|Mac OS X}} |
||
< |
<syntaxhighlight lang="objc">#import <CommonCrypto/CommonDigest.h> |
||
NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; |
NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; |
||
Line 922: | Line 3,329: | ||
} |
} |
||
NSLog(@"%@", hex); |
NSLog(@"%@", hex); |
||
}</ |
}</syntaxhighlight> |
||
{{works with|Mac OS X}} (need to include "libcrypto.dylib" framework) |
{{works with|Mac OS X}} (need to include "libcrypto.dylib" framework) |
||
< |
<syntaxhighlight lang="objc">#include <openssl/md5.h> |
||
NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; |
NSString *myString = @"The quick brown fox jumped over the lazy dog's back"; |
||
Line 936: | Line 3,343: | ||
} |
} |
||
NSLog(@"%@", hex); |
NSLog(@"%@", hex); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml"># Digest.to_hex(Digest.string "The quick brown fox jumped over the lazy dog's back") ;; |
||
- : string = "e38ca1d920c4b8b8d3946b2c72f01680"</ |
- : string = "e38ca1d920c4b8b8d3946b2c72f01680"</syntaxhighlight> |
||
=={{header|Octave}}== |
=={{header|Octave}}== |
||
< |
<syntaxhighlight lang="octave">s = "The quick brown fox jumped over the lazy dog's back"; |
||
hash = md5sum(s, true); |
hash = md5sum(s, true); |
||
disp(hash)</ |
disp(hash)</syntaxhighlight> |
||
For an implementation of MD5, see [[{{FULLPAGENAME}}#MATLAB|MATLAB example]]. |
|||
=={{header|Ol}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(import (otus ffi)) |
|||
(define libcrypto (load-dynamic-library "libcrypto.so.1.0.0")) |
|||
(define MD5 (libcrypto type-vptr "MD5" type-string fft-unsigned-long type-string)) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="scheme"> |
|||
(define (test str) |
|||
(define md5 "----------------") |
|||
(MD5 str (string-length str) md5) |
|||
(for-each display (list "\"" str "\": ")) |
|||
(for-each (lambda (c) |
|||
(define hex "0123456789abcdef") |
|||
(display (string (ref hex (>> c 4)))) |
|||
(display (string (ref hex (band c #x0F))))) |
|||
(string->list md5)) |
|||
(print)) |
|||
(test "") |
|||
(test "a") |
|||
(test "abc") |
|||
(test "message digest") |
|||
(test "abcdefghijklmnopqrstuvwxyz") |
|||
(test "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") |
|||
(test "12345678901234567890123456789012345678901234567890123456789012345678901234567890")</syntaxhighlight> |
|||
<pre> |
|||
"": d41d8cd98f00b204e9800998ecf8427e |
|||
"a": 0cc175b9c0f1b6a831c399e269772661 |
|||
"abc": 900150983cd24fb0d6963f7d28e17f72 |
|||
"message digest": f96b697d7cb7938d525a2f31aaf161d0 |
|||
"abcdefghijklmnopqrstuvwxyz": c3fcd3d76192e4007dfb496cca67e13b |
|||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": d174ab98d277d9f5a5611c2c9f419d9f |
|||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890": 57edf4a22be3c955ac49da2e2107b67a |
|||
</pre> |
|||
=={{header|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. |
|||
<syntaxhighlight lang="openedge/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</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
--------------------------- |
|||
Message |
|||
--------------------------- |
|||
1 d41d8cd98f00b204e9800998ecf8427e |
|||
2 0cc175b9c0f1b6a831c399e269772661 |
|||
3 900150983cd24fb0d6963f7d28e17f72 |
|||
4 f96b697d7cb7938d525a2f31aaf161d0 |
|||
5 c3fcd3d76192e4007dfb496cca67e13b |
|||
6 d174ab98d277d9f5a5611c2c9f419d9f |
|||
7 57edf4a22be3c955ac49da2e2107b67a |
|||
--------------------------- |
|||
OK |
|||
--------------------------- |
|||
</pre> |
|||
=={{header|PARI/GP}}== |
|||
Build a MD5 plugin using Linux system library and PARI's function interface. (Linux solution) |
|||
<syntaxhighlight 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); |
|||
}</syntaxhighlight> |
|||
Compile with: gcc -Wall -O2 -fPIC -shared md5.c -o libmd5.so -lcrypt -lpari |
|||
Load plugin from your home directory into PARI: |
|||
<syntaxhighlight lang="parigp">install("plug_md5", "s", "MD5", "~/libmd5.so"); |
|||
MD5("The quick brown fox jumped over the lazy dog's back") </syntaxhighlight> |
|||
Output: |
|||
<pre>"e38ca1d920c4b8b8d3946b2c72f01680"</pre> |
|||
Here is an explicit implementation in the PARI/GP language: |
|||
<syntaxhighlight lang="parigp">md5( message ) = { my( |
|||
a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, |
|||
s = [ 7, 12, 17, 22; 5, 9, 14, 20; 4, 11, 16, 23; 6, 10, 15, 21 ], |
|||
msg = concat( Vec( concat(Vecsmall(message), Vecsmall(128)), (#message + 9) \ 64 * 64 + 56 ), |
|||
Vecrev(digits( #message % 2^61 * 8, 256), 8)), \\ little endian ! |
|||
leftrotate(x, c) = x << c + x >> (32-c) |
|||
); |
|||
\\*** Process the message in successive 512-bit chunks *** |
|||
forstep( m=1, #msg, 512/8, |
|||
my( \\ break chunk into 32-bit words M[j] - LITTLE ENDIAN ! |
|||
M = vector( 16, j, fromdigits( Vecrev(msg[ m + j*4 - 4 .. m + j*4 - 1 ]), 2^8 )), |
|||
A = a, B = b, C = c, D = d); |
|||
for( i = 0 , 63 , [A, D, C, B] = [D, C, B, B + leftrotate( ( A + abs(sin(i+1))\2^-32 + |
|||
if( i < 16 , bitor( bitand(B , C) , bitand( bitneg(B) , D)) + M[ i +1] |
|||
, i < 32 , bitor( bitand(D , B) , bitand( bitneg(D) , C)) + M[ (5*i + 1) % 16 +1] |
|||
, i < 48 , bitxor( bitxor( B , C ) , D ) + M[ (3*i + 5) % 16 +1] |
|||
, bitxor( C , bitor( bitneg(D), B)) + M[ 7*i % 16 +1] |
|||
)) % 2^32, s[i\16+1, i%4+1] )] |
|||
); \\ end for |
|||
[a,b,c,d] = ([a,b,c,d] + [A,B,C,D]) % 2^32 ; |
|||
); \\ end forstep |
|||
Strprintf("%032x",fromdigits(Vecrev(digits(fromdigits([d,c,b,a],2^32),256),16),256)) |
|||
}</syntaxhighlight> |
|||
Then: |
|||
<syntaxhighlight lang="parigp">gp > md5("")</syntaxhighlight> |
|||
<pre> |
|||
%2 = "d41d8cd98f00b204e9800998ecf8427e" |
|||
</pre> |
|||
<syntaxhighlight lang="parigp">gp > md5("The quick brown fox jumps over lazy dogs.")</syntaxhighlight> |
|||
<pre> |
|||
%3 = "4c57070257998981a0c7b7ec003b9d5c" |
|||
</pre> |
|||
==Pascal== |
|||
Pascal has a built-in unit called md5. It can be used to get a digest both for a string and a file. |
|||
<syntaxhighlight lang="pascal"> |
|||
program GetMd5; |
|||
uses md5; |
|||
var |
|||
strEncrypted : string; |
|||
begin |
|||
strEncrypted := md5Print(md5String('The quick brown fox jumped over the lazy dog''s back')); |
|||
writeln(strEncrypted); |
|||
end. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</pre> |
|||
To digest a file, use md5Print(md5File('myfile.txt')) where myfile.txt is a file. |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
{{libheader|Digest::MD5}} |
{{libheader|Digest::MD5}} |
||
< |
<syntaxhighlight lang="perl">use Digest::MD5 qw(md5_hex); |
||
print md5_hex("The quick brown fox jumped over the lazy dog's back"), "\n";</ |
print md5_hex("The quick brown fox jumped over the lazy dog's back"), "\n";</syntaxhighlight> |
||
The same in OO manner |
The same in OO manner |
||
< |
<syntaxhighlight lang="perl">use Digest::MD5; |
||
$md5 = Digest::MD5->new; |
$md5 = Digest::MD5->new; |
||
$md5->add("The quick brown fox jumped over the lazy dog's back"); |
$md5->add("The quick brown fox jumped over the lazy dog's back"); |
||
print $md5->hexdigest, "\n";</ |
print $md5->hexdigest, "\n";</syntaxhighlight> |
||
=={{header| |
=={{header|Phix}}== |
||
<!--(phixonline)--> |
|||
Library [http://github.com/cosimo/perl6-digest-md5/ Digest::MD5] |
|||
See [[MD5/Implementation#Phix]] |
|||
<lang> |
|||
use Digest::MD5; |
|||
say Digest::MD5.md5_hex: "The quick brown fox jumped over the lazy dog's back"; |
|||
</lang> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
<syntaxhighlight lang="php">$string = "The quick brown fox jumped over the lazy dog's back"; |
|||
echo md5( $string );</syntaxhighlight> |
|||
<lang php>$string = "The quick brown fox jumped over the lazy dog's back"; |
|||
echo md5( $string );</lang> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Using the openssl library (the 'native' function is only in the 64-bit |
Using the openssl library (the 'native' function is only in the 64-bit |
||
version available): |
version available): |
||
< |
<syntaxhighlight lang="picolisp">(let Str "The quick brown fox jumped over the lazy dog's back" |
||
(pack |
(pack |
||
(mapcar hex |
(mapcar '((B) (pad 2 (hex B))) |
||
(native "libcrypto.so" "MD5" '(B . 16) Str (length Str) '(NIL (16))) ) ) )</ |
(native "libcrypto.so" "MD5" '(B . 16) Str (length Str) '(NIL (16))) ) ) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>-> "E38CA1D920C4B8B8D3946B2C72F01680"</pre> |
<pre>-> "E38CA1D920C4B8B8D3946B2C72F01680"</pre> |
||
=={{header|Pike}}== |
=={{header|Pike}}== |
||
< |
<syntaxhighlight lang="pike">import String; |
||
import Crypto.MD5; |
import Crypto.MD5; |
||
int main(){ |
int main(){ |
||
write( string2hex( hash( "The quick brown fox jumped over the lazy dog's back" ) ) + "\n" ); |
write( string2hex( hash( "The quick brown fox jumped over the lazy dog's back" ) ) + "\n" ); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="powershell">$string = "The quick brown fox jumped over the lazy dog's back" |
||
$data = [Text.Encoding]::UTF8.GetBytes($string) |
$data = [Text.Encoding]::UTF8.GetBytes($string) |
||
$hash = [Security.Cryptography.MD5]::Create().ComputeHash($data) |
$hash = [Security.Cryptography.MD5]::Create().ComputeHash($data) |
||
([BitConverter]::ToString($hash) -replace '-').ToLower()</ |
([BitConverter]::ToString($hash) -replace '-').ToLower()</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
;Purebasic 5.x versions: |
|||
<lang purebasic>test$ = "The quick brown fox jumped over the lazy dog's back" |
|||
<syntaxhighlight lang="purebasic">UseMD5Fingerprint() ; register the MD5 fingerprint plugin |
|||
Debug MD5Fingerprint(@test$, StringByteLength(test$))</lang> |
|||
test$ = "The quick brown fox jumped over the lazy dog's back" |
|||
; Call StringFingerprint() function and display MD5 result in Debug window |
|||
Debug StringFingerprint(test$, #PB_Cipher_MD5) |
|||
</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Using builtin libraries: |
Using builtin libraries: |
||
Python 2.5 and later: |
;Python 3.x, 2.5 and later 2.x versions: |
||
< |
<syntaxhighlight 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 |
|||
>>> </syntaxhighlight> |
|||
;Python 2.5 and later: |
|||
<syntaxhighlight lang="python">>>> import hashlib |
|||
>>> print hashlib.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() |
>>> print hashlib.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() |
||
e38ca1d920c4b8b8d3946b2c72f01680</ |
e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
||
Pre-2.5; removed in 3.x: |
;Pre-2.5; removed in 3.x: |
||
< |
<syntaxhighlight lang="python">>>> import md5 |
||
>>> print md5.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() |
>>> print md5.md5("The quick brown fox jumped over the lazy dog's back").hexdigest() |
||
e38ca1d920c4b8b8d3946b2c72f01680</ |
e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="r">library(digest) |
||
hexdigest <- digest("The quick brown fox jumped over the lazy dog's back", |
hexdigest <- digest("The quick brown fox jumped over the lazy dog's back", |
||
algo="md5", serialize=FALSE)</ |
algo="md5", serialize=FALSE)</syntaxhighlight> |
||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require file/md5) |
|||
(md5 "") |
|||
(md5 "a") |
|||
(md5 "abc") |
|||
(md5 "message digest") |
|||
(md5 "abcdefghijklmnopqrstuvwxyz") |
|||
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") |
|||
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890") |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
#"d41d8cd98f00b204e9800998ecf8427e" |
|||
#"0cc175b9c0f1b6a831c399e269772661" |
|||
#"900150983cd24fb0d6963f7d28e17f72" |
|||
#"f96b697d7cb7938d525a2f31aaf161d0" |
|||
#"c3fcd3d76192e4007dfb496cca67e13b" |
|||
#"d174ab98d277d9f5a5611c2c9f419d9f" |
|||
#"57edf4a22be3c955ac49da2e2107b67a" |
|||
</pre> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
Library [http://github.com/cosimo/perl6-digest-md5/ Digest::MD5] |
|||
<syntaxhighlight lang="raku" line>use Digest::MD5; |
|||
say Digest::MD5.md5_hex: "The quick brown fox jumped over the lazy dog's back";</syntaxhighlight> |
|||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
<syntaxhighlight lang="rebol">>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 |
|||
<lang rebol> |
|||
== #{08A008A01D498C404B0C30852B39D3B8}</syntaxhighlight> |
|||
>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5 |
|||
== #{08A008A01D498C404B0C30852B39D3B8}</lang> |
|||
=={{header| |
=={{header|REXX}}== |
||
<syntaxhighlight 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*/ /*────step────*/ |
|||
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)</syntaxhighlight> |
|||
'''output''' when using the default (internal) inputs: |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
See MD5("my string!") + nl |
|||
# output : a83a049fbe50cf7334caa86bf16a3520 |
|||
</syntaxhighlight> |
|||
=={{header|RLaB}}== |
|||
RLaB has a built-in function ''hash,'' |
RLaB has a built-in function ''hash,'' |
||
:<math>hs = hash(fn, s /, nl/) </math> |
:<math>hs = hash(fn, s /, nl/) </math> |
||
Line 1,032: | Line 3,796: | ||
calculated in RLaB is the same as the hash of the same string vector written to a file. |
calculated in RLaB is the same as the hash of the same string vector written to a file. |
||
<syntaxhighlight lang="rlab">>> x = "The quick brown fox jumped over the lazy dog's back" |
|||
<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 |
The quick brown fox jumped over the lazy dog's back |
||
>> hash("md5", x) |
>> hash("md5", x) |
||
e38ca1d920c4b8b8d3946b2c72f01680 |
e38ca1d920c4b8b8d3946b2c72f01680</syntaxhighlight> |
||
</lang> |
|||
=={{header|RPG}}== |
|||
Modified from [http://www.mysamplecode.com/2011/05/rpgle-generate-sha-1-hash-use.html]: |
|||
<syntaxhighlight lang="rpg">**FREE |
|||
Ctl-opt MAIN(Main); |
|||
Ctl-opt DFTACTGRP(*NO) ACTGRP(*NEW); |
|||
dcl-pr QDCXLATE EXTPGM('QDCXLATE'); |
|||
dataLen packed(5 : 0) CONST; |
|||
data char(32767) options(*VARSIZE); |
|||
conversionTable char(10) CONST; |
|||
end-pr; |
|||
dcl-pr Qc3CalculateHash EXTPROC('Qc3CalculateHash'); |
|||
inputData pointer value; |
|||
inputDataLen int(10) const; |
|||
inputDataFormat char(8) const; |
|||
algorithmDscr char(16) const; |
|||
algorithmFormat char(8) const; |
|||
cryptoServiceProvider char(1) const; |
|||
cryptoDeviceName char(1) const options(*OMIT); |
|||
hash char(64) options(*VARSIZE : *OMIT); |
|||
errorCode char(32767) options(*VARSIZE); |
|||
end-pr; |
|||
dcl-c HEX_CHARS CONST('0123456789ABCDEF'); |
|||
dcl-proc Main; |
|||
dcl-s inputData char(45); |
|||
dcl-s inputDataLen int(10) INZ(0); |
|||
dcl-s outputHash char(16); |
|||
dcl-s outputHashHex char(32); |
|||
dcl-ds algorithmDscr QUALIFIED; |
|||
hashAlgorithm int(10) INZ(0); |
|||
end-ds; |
|||
dcl-ds ERRC0100_NULL QUALIFIED; |
|||
bytesProvided int(10) INZ(0); // Leave at zero |
|||
bytesAvailable int(10); |
|||
end-ds; |
|||
dow inputDataLen = 0; |
|||
DSPLY 'Input: ' '' inputData; |
|||
inputData = %trim(inputData); |
|||
inputDataLen = %len(%trim(inputData)); |
|||
DSPLY ('Input=' + inputData); |
|||
DSPLY ('InputLen=' + %char(inputDataLen)); |
|||
if inputDataLen = 0; |
|||
DSPLY 'Input must not be blank'; |
|||
endif; |
|||
enddo; |
|||
// Convert from EBCDIC to ASCII |
|||
QDCXLATE(inputDataLen : inputData : 'QTCPASC'); |
|||
algorithmDscr.hashAlgorithm = 1; // MD5 |
|||
// Calculate hash |
|||
Qc3CalculateHash(%addr(inputData) : inputDataLen : 'DATA0100' : algorithmDscr |
|||
: 'ALGD0500' : '0' : *OMIT : outputHash : ERRC0100_NULL); |
|||
// Convert to hex |
|||
CVTHC(outputHashHex : outputHash : 32); |
|||
DSPLY ('MD5: ' + outputHashHex); |
|||
return; |
|||
end-proc; |
|||
// This procedure is actually a MI, but I couldn't get it to bind so I wrote my own version |
|||
dcl-proc CVTHC; |
|||
dcl-pi *N; |
|||
target char(65534) options(*VARSIZE); |
|||
srcBits char(32767) options(*VARSIZE) CONST; |
|||
targetLen int(10) value; |
|||
end-pi; |
|||
dcl-s i int(10); |
|||
dcl-s lowNibble ind INZ(*OFF); |
|||
dcl-s inputOffset int(10) INZ(1); |
|||
dcl-ds dataStruct QUALIFIED; |
|||
numField int(5) INZ(0); |
|||
// IBM i is big-endian |
|||
charField char(1) OVERLAY(numField : 2); |
|||
end-ds; |
|||
for i = 1 to targetLen; |
|||
if lowNibble; |
|||
dataStruct.charField = %BitAnd(%subst(srcBits : inputOffset : 1) : X'0F'); |
|||
inputOffset += 1; |
|||
else; |
|||
dataStruct.charField = %BitAnd(%subst(srcBits : inputOffset : 1) : X'F0'); |
|||
dataStruct.numField /= 16; |
|||
endif; |
|||
%subst(target : i : 1) = %subst(HEX_CHARS : dataStruct.numField + 1 : 1); |
|||
lowNibble = NOT lowNibble; |
|||
endfor; |
|||
return; |
|||
end-proc;</syntaxhighlight> |
|||
Note that this implementation converts the input from EBCDIC to ASCII before computing the hash. |
|||
Sample output: |
|||
<pre> DSPLY Input: |
|||
abcdefghijklmnopqrstuvwxyz |
|||
DSPLY Input=abcdefghijklmnopqrstuvwxyz |
|||
DSPLY InputLen=26 |
|||
DSPLY MD5: C3FCD3D76192E4007DFB496CCA67E13B</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">require 'digest' |
||
Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back") |
Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back") |
||
# => "e38ca1d920c4b8b8d3946b2c72f01680"</ |
# => "e38ca1d920c4b8b8d3946b2c72f01680"</syntaxhighlight> |
||
=={{header| |
=={{header|Rust}}== |
||
Cargo.toml |
|||
<syntaxhighlight lang="toml"> |
|||
[dependencies] |
|||
rust-crypto = "0.2" |
|||
</syntaxhighlight> |
|||
src/main.rs |
|||
<syntaxhighlight 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()); |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|S-lang}}== |
|||
Support for MD5 and SHA-1 are included in the standard "chksum" library: |
|||
<syntaxhighlight lang="s-lang">require("chksum"); |
|||
print(md5sum("The quick brown fox jumped over the lazy dog's back"));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>"e38ca1d920c4b8b8d3946b2c72f01680"</pre> |
|||
=={{header|Scala}}== |
|||
<syntaxhighlight 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]") |
|||
}</syntaxhighlight> |
|||
=={{header|Seed7}}== |
|||
<syntaxhighlight 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;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
e38ca1d920c4b8b8d3946b2c72f01680 |
|||
</pre> |
|||
=={{header|Sidef}}== |
|||
{{libheader|Digest::MD5}} |
|||
<syntaxhighlight lang="ruby">var digest = frequire('Digest::MD5'); |
|||
say digest.md5_hex("The quick brown fox jumped over the lazy dog's back");</syntaxhighlight> |
|||
The same in OO manner |
|||
<syntaxhighlight lang="ruby">var md5 = require('Digest::MD5').new; |
|||
md5.add("The quick brown fox jumped over the lazy dog's back"); |
|||
say md5.hexdigest;</syntaxhighlight> |
|||
=={{header|Slate}}== |
|||
You must load the code in 'src/lib/md5.slate'. |
You must load the code in 'src/lib/md5.slate'. |
||
<syntaxhighlight lang="slate">'The quick brown fox jumped over the lazy dog\'s back' md5String. "==> 'e38ca1d920c4b8b8d3946b2c72f01680'"</syntaxhighlight> |
|||
<lang slate> |
|||
'The quick brown fox jumped over the lazy dog\'s back' md5String. "==> 'e38ca1d920c4b8b8d3946b2c72f01680'" |
|||
</lang> |
|||
=={{header|Slope}}== |
|||
<syntaxhighlight lang="slope">(display (string->md5 "The quick brown fox jumped over the lazy dog's back"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e38ca1d920c4b8b8d3946b2c72f01680</pre> |
|||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
Using utility classes: |
|||
{{works with|GNU Smalltalk}} |
{{works with|GNU Smalltalk}} |
||
< |
<syntaxhighlight lang="smalltalk">PackageLoader fileInPackage: 'Digest' ! |
||
(MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dog''s back') displayNl.</ |
(MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dog''s back') displayNl.</syntaxhighlight> |
||
{{works with|Smalltalk/X}} |
|||
<syntaxhighlight lang="smalltalk">(MD5Stream hashValueOf: 'The quick brown fox jumped over the lazy dog''s back') printCR.</syntaxhighlight> |
|||
=={{header|SQL}}== |
=={{header|SQL}}== |
||
{{works with|MySQL}} |
{{works with|MySQL}} |
||
<syntaxhighlight lang="sql">SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')</syntaxhighlight> |
|||
<lang sql>SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')</lang> |
|||
=={{header|Suneido}}== |
=={{header|Suneido}}== |
||
< |
<syntaxhighlight lang="suneido">Md5('The quick brown fox jumped over the lazy dog\'s back')</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{tcllib|md5}} |
{{tcllib|md5}} |
||
< |
<syntaxhighlight lang="tcl">package require md5 |
||
puts [md5::md5 -hex "The quick brown fox jumped over the lazy dog's back"] |
puts [md5::md5 -hex "The quick brown fox jumped over the lazy dog's back"] |
||
# ==> E38CA1D920C4B8B8D3946B2C72F01680</ |
# ==> E38CA1D920C4B8B8D3946B2C72F01680</syntaxhighlight> |
||
=={{header|UNIX Shell}}== |
=={{header|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'': |
|||
<syntaxhighlight lang="bash">echo -n "The quick brown fox jumped over the lazy dog's back" | md5sum</syntaxhighlight> |
|||
Several [[BSD]] systems have ''md5:'' |
|||
<syntaxhighlight lang="bash">echo -n "The quick brown fox jumped over the lazy dog's back" | md5</syntaxhighlight> |
|||
{{libheader|OpenSSL}} |
|||
<syntaxhighlight lang="bash">echo -n "The quick brown fox jumped over the lazy dog's back" | |
|||
openssl md5 | sed 's/.*= //'</syntaxhighlight> |
|||
=={{header|Visual Basic .NET}}== |
|||
{{works with|Visual Basic .NET|9.0+}} |
|||
<syntaxhighlight lang="vbnet">Imports System.Security.Cryptography |
|||
Imports System.Text |
|||
Module MD5hash |
|||
Sub Main(args As String()) |
|||
Console.WriteLine(GetMD5("Visual Basic .Net")) |
|||
End Sub |
|||
Private Function GetMD5(plainText As String) As String |
|||
Dim hash As String = "" |
|||
Using hashObject As MD5 = MD5.Create() |
|||
Dim ptBytes As Byte() = hashObject.ComputeHash(Encoding.UTF8.GetBytes(plainText)) |
|||
Dim hashBuilder As New StringBuilder |
|||
For i As Integer = 0 To ptBytes.Length - 1 |
|||
hashBuilder.Append(ptBytes(i).ToString("X2")) |
|||
Next |
|||
hash = hashBuilder.ToString |
|||
End Using |
|||
Return hash |
|||
End Function |
|||
End Module |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
AF397EA30996B22759740AC66452D47A |
|||
</pre> |
|||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">import crypto.md5 |
|||
fn main() { |
|||
for p in [ |
|||
// 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]) |
|||
} |
|||
} |
|||
fn validate(check string, s string) { |
|||
sum := md5.hexhash(s) |
|||
if sum != check { |
|||
println("MD5 fail") |
|||
println(" for string, $s") |
|||
println(" expected: $check") |
|||
println(" got: $sum") |
|||
} else { |
|||
println('MD5 succeeded $s') |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>MD5 succeeded |
|||
MD5 succeeded a |
|||
MD5 succeeded abc |
|||
MD5 succeeded message digest |
|||
MD5 succeeded abcdefghijklmnopqrstuvwxyz |
|||
MD5 succeeded ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 |
|||
MD5 succeeded 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|||
MD5 succeeded The quick brown fox jumped over the lazy dog's back |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{libheader|Wren-crypto}} |
|||
{{libheader|Wren-fmt}} |
|||
This script uses a library implementation of MD5 (based on the implementation in the [[MD5/Implementation#Wren]] task) to process the Wikipedia examples. |
|||
<syntaxhighlight lang="wren">import "./crypto" for Md5 |
|||
import "./fmt" for Fmt |
|||
var strings = [ |
|||
"The quick brown fox jumps over the lazy dog", |
|||
"The quick brown fox jumps over the lazy dog.", |
|||
"" |
|||
] |
|||
for (s in strings) { |
|||
var digest = Md5.digest(s) |
|||
Fmt.print("$s <== '$0s'", digest, s) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
9e107d9d372bb6826bd81d3542a419d6 <== 'The quick brown fox jumps over the lazy dog' |
|||
e4d909c290d0fb1ca068ffaddf22cbd0 <== 'The quick brown fox jumps over the lazy dog.' |
|||
d41d8cd98f00b204e9800998ecf8427e <== '' |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
md5 is a built in utility |
|||
<syntaxhighlight lang="zkl">Utils.MD5.calc("message digest"); //-->"f96b697d7cb7938d525a2f31aaf161d0" |
|||
Utils.MD5.calc("abcdefghijklmnopqrstuvwxyz"); //-->"c3fcd3d76192e4007dfb496cca67e13b"</syntaxhighlight> |
|||
{{omit from|GUISS}} |
|||
[[Wikipedia::http://en.wikipedia.org/wiki/MD5]] |
|||
<lang bash>echo -n "The quick brown fox jumped over the lazy dog's back" | md5sum</lang> |
Latest revision as of 07:00, 9 August 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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, RFC 1321 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
"md5" cr:hash! "Some text" cr:hash cr:hash>s
. cr bye
- Output:
9db5682a4d778ca2cb79580bdb67083f
AArch64 Assembly
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program MD5_64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ MD5_DIGEST_LENGTH, 16
.equ ZWORKSIZE, 1000
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessRosetta: .asciz "Rosetta Code"
szMessTest1: .asciz ""
szMessTest2: .asciz "abc"
szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz"
szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
szMessTest5: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
szMessFinPgm: .asciz "Program End ok.\n"
szMessResult: .asciz "Result for "
szMessResult1: .asciz " => "
szMessSizeError: .asciz "\033[31mWork area too small !! \033[0m \n"
szCarriageReturn: .asciz "\n"
/* array constantes K */
tbConstK: .int 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee
.int 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501
.int 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be
.int 0x6b901122,0xfd987193,0xa679438e,0x49b40821
.int 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa
.int 0xd62f105d,0x2441453,0xd8a1e681,0xe7d3fbc8
.int 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed
.int 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a
.int 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c
.int 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70
.int 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x4881d05
.int 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665
.int 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039
.int 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1
.int 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1
.int 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
/* array rotation coef R */
tbRotaR: .int 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22
.int 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20
.int 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23
.int 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
tbConstH: .int 0x67452301 // H0
.int 0xEFCDAB89 // H1
.int 0x98BADCFE // H2
.int 0x10325476 // H3
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
//iNbBlocs: .skip 8
sZoneConv: .skip 24
sZoneResult: .skip 24
tbH: .skip 4 * 4 // 4 variables H
sZoneTrav: .skip ZWORKSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessTest1
bl computeExemple
ldr x0,qAdrszMessTest2
bl computeExemple
ldr x0,qAdrszMessTest3
bl computeExemple
ldr x0,qAdrszMessTest4
bl computeExemple
ldr x0,qAdrszMessTest5
bl computeExemple
ldr x0,qAdrszMessFinPgm
bl affichageMess // display message
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessResult: .quad szMessResult
qAdrszMessResult1: .quad szMessResult1
qAdrszMessRosetta: .quad szMessRosetta
qAdrszMessTest1: .quad szMessTest1
qAdrszMessTest2: .quad szMessTest2
qAdrszMessTest3: .quad szMessTest3
qAdrszMessTest4: .quad szMessTest4
qAdrszMessTest5: .quad szMessTest5
qAdrsZoneTrav: .quad sZoneTrav
qAdrsZoneConv: .quad sZoneConv
qAdrszMessFinPgm: .quad szMessFinPgm
/***********************************************/
/* compute exemple */
/***********************************************/
/* x0 contains the address of the message */
computeExemple:
stp x18,lr,[sp,-16]! // save registers
mov x18,x0
bl computeMD5 // call routine MD5
ldr x0,qAdrszMessResult
bl affichageMess
mov x0,x18
bl affichageMess
ldr x0,qAdrszMessResult1
bl affichageMess
ldr x0, qAdrsZoneResult
bl displayMD5
100:
ldp x18,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* compute MD5 */
/******************************************************************/
/* x0 contains the address of the message */
computeMD5:
stp x1,lr,[sp,-16]! // save registers
ldr x1,qAdrsZoneTrav
mov x2,#0 // counter length
1: // copy string in work area
cmp x2,ZWORKSIZE
bge 99f
ldrb w3,[x0,x2]
strb w3,[x1,x2]
cmp x3,#0
add x4,x2,1
csel x2,x4,x2,ne
bne 1b
// add bit et compute length
lsl x6,x2,#3 // initial message length in bits
mov x3,#0b10000000 // add bit 1 at end of string
strb w3,[x1,x2]
add x2,x2,#1 // length in bytes
lsl x4,x2,#3 // length in bits
mov x3,#0
2:
lsr x5,x2,#6 // padding block 512 bytes
lsl x5,x5,#6
sub x5,x2,x5
cmp x5,#56
beq 3f // yes -> end add
strb w3,[x1,x2] // add zero at message end
add x2,x2,#1 // increment length bytes
add x4,x4,#8 // increment length in bits
b 2b
3:
str x6,[x1,x2] // and store at end
ldr x7,qAdrtbConstH // constantes H address
ldr x4,qAdrtbH // start area H
mov x5,#0
4: // init array H with start constantes
ldr w6,[x7,x5,lsl #2] // load constante
str w6,[x4,x5,lsl #2] // and store
add x5,x5,#1
cmp x5,#4 // constantes number
blt 4b
// split into block of 64 bytes
add x2,x2,#4 // TODO : à revoir
lsr x4,x2,#6 // blocks number
mov x7,#0 // no de block et x1 contient l'adresse zone de travail
ldr x3,qAdrtbConstK // K constantes address
ldr x5,qAdrtbRotaR // R rotation address
5: // begin loop of each block of 64 bytes
// init variable a b c d with H0 H1 H2 H3
ldr x0,qAdrtbH
ldr w8,[x0] // a
ldr w9,[x0,#4] // b
ldr w10,[x0,#8] // c
ldr w11,[x0,#12] // d
mov x6,#0 // indice t
/* x2 address begin each block */
ldr x1,qAdrsZoneTrav
add x2,x1,x7,lsl #6 // compute block begin indice * 4 * 16
6: // begin loop one
cmp x6,15
bgt 7f
// cas 1 f := (b et c) ou ((non b) et d)
// g := i
and w12,w9,w10
mvn w13,w9
and w13,w13,w11
orr w12,w12,w13 // f
mov x14,x6 // g
b 10f
7:
cmp x6,31
bgt 8f
// f := (d et b) ou ((non d) et c)
// g := (5×i + 1) mod 16
and w12,w11,w9
mvn w13,w11
and w13,w13,w10
orr w12,w12,w13 // f
mov x13,5
mul x13,x6,x13
add x13,x13,1
lsr x15,x13,4
lsl x15,x15,4
sub x14,x13,x15
b 10f
8:
cmp x6,47
bgt 9f
// f := b xor c xor d
// g := (3×i + 5) mod 16
eor w12,w9,w10
eor w12,w12,w11
mov x13,3
mul x13,x6,x13
add x13,x13,5
lsr x15,x13,4
lsl x15,x15,4
sub x14,x13,x15
b 10f
9:
// f := c xor (b ou (non d))
// g := (7×i) mod 16
mvn w13,w11
orr w13,w13,w9
eor w12,w13,w10 // f
mov x13,7
mul x13,x6,x13
lsr x15,x13,4
lsl x15,x15,4
sub x14,x13,x15 // g
10:
mov w15,w11
mov w11,w10 // d = c
mov w10,w9 // c = b
add w16,w8,w12 // a + f
ldr w17,[x2,x14,lsl #2]
add w16,w16,w17 // + valeur bloc g
ldr w13,[x3,x6,lsl #2]
add w16,w16,w13 // + valeur constante K de i
ldr w17,[x5,x6,lsl #2] // rotate left value
mov w13,32
sub w17,w13,w17
ror w13,w16,w17
add w9,w9,w13 // new b
mov w8, w15 // new a
add x6,x6,1
cmp x6,63
ble 6b
ldr x0,qAdrtbH
ldr w1,[x0] // H0
add w1,w1,w8 // + a
str w1,[x0]
ldr w1,[x0,#4] // H1
add w1,w1,w9 // + b
str w1,[x0,#4]
ldr w1,[x0,#8] // H2
add w1,w1,w10 // + c
str w1,[x0,#8]
ldr w1,[x0,#12] // H3
add w1,w1,w11 // + d
str w1,[x0,#12]
// other bloc
add x7,x7,1 // increment block
cmp x7,x4 // maxi ?
ble 5b
// compute final result
ldr x0,qAdrtbH // start area H
ldr x2,qAdrsZoneResult
ldr w1,[x0]
str w1,[x2]
ldr w1,[x0,#4]
str w1,[x2,#4]
ldr w1,[x0,#8]
str w1,[x2,#8]
ldr w1,[x0,#12]
str w1,[x2,#12]
mov x0,#0 // routine OK
b 100f
99: // size error
ldr x0,qAdrszMessSizeError
bl affichageMess
mov x0,-1
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrtbConstH: .quad tbConstH
qAdrtbConstK: .quad tbConstK
qAdrtbRotaR: .quad tbRotaR
qAdrtbH: .quad tbH
qAdrsZoneResult: .quad sZoneResult
qAdrszMessSizeError: .quad szMessSizeError
/******************************************************************/
/* display hash MD5 */
/******************************************************************/
/* x0 contains the address of hash */
displayMD5:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
mov x3,x0
mov x2,#0
1:
ldr w0,[x3,x2,lsl #2] // load 4 bytes
rev w0,w0 // reverse bytes
ldr x1,qAdrsZoneConv
bl conversion16_4W // conversion hexa
ldr x0,qAdrsZoneConv
bl affichageMess
add x2,x2,#1
cmp x2,#MD5_DIGEST_LENGTH / 4
blt 1b // and loop
ldr x0,qAdrszCarriageReturn
bl affichageMess // display message
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* conversion hexadecimal register 32 bits */
/******************************************************************/
/* x0 contains value and x1 address zone receptrice */
conversion16_4W:
stp x0,lr,[sp,-48]! // save registres
stp x1,x2,[sp,32] // save registres
stp x3,x4,[sp,16] // save registres
mov x2,#28 // start bit position
mov x4,#0xF0000000 // mask
mov x3,x0 // save entry value
1: // start loop
and x0,x3,x4 // value register and mask
lsr x0,x0,x2 // right shift
cmp x0,#10 // >= 10 ?
bge 2f // yes
add x0,x0,#48 // no is digit
b 3f
2:
add x0,x0,#55 // else is a letter A-F
3:
strb w0,[x1],#1 // load result and + 1 in address
lsr x4,x4,#4 // shift mask 4 bits left
subs x2,x2,#4 // decrement counter 4 bits <= zero ?
bge 1b // no -> loop
100: // fin standard de la fonction
ldp x3,x4,[sp,16] // restaur des 2 registres
ldp x1,x2,[sp,32] // restaur des 2 registres
ldp x0,lr,[sp],48 // restaur des 2 registres
ret
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
Result for => D41D8CD98F00B204E9800998ECF8427E Result for abc => 900150983CD24FB0D6963F7D28E17F72 Result for abcdefghijklmnopqrstuvwxyz => C3FCD3D76192E4007DFB496CCA67E13B Result for 12345678901234567890123456789012345678901234567890123456789012345678901234567890 => 57EDF4A22BE3C955AC49DA2E2107B67A Result for ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 => D174AB98D277D9F5A5611C2C9F419D9F Program End ok.
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;
ALGOL 68
# 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
APL
md5←{
⍝ index origin zero
⎕IO←0
⍝ decoding UTF-8 & padding
M←(⊢,(0⍴⍨512|448-512|≢))1,⍨l←,⍉(8⍴2)⊤'UTF-8'⎕UCS ⍵
⍝ add length
M,←,⍉(8⍴2)⊤⌽(8⍴256)⊤≢l
⍝ init registers
A←16⊥6 7 4 5 2 3 0 1
B←16⊥14 15 12 13 10 11 8 9
C←16⊥9 8 11 10 13 12 15 14
D←16⊥1 0 3 2 5 4 7 6
⍝ T table
T←⌊(2*32)×|1○1+⍳64
⍝ index table
K←16|i,(1+5×i),(5+3×i),7×i←⍳16
⍝ rot table
S←,1 0 2⍉4 4 4⍴7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21
⍝ truncate ⍵ to 32 bit & rot left ⍺
rot←{2⊥⍺⌽(32⍴2)⊤⍵}
proc←{
⍝ pack 512 bits into 32 bit words &
⍝ precompute X[k] + T[i]
l←T+(⊂K)⌷256⊥⍉⌽16 4⍴2⊥⍉64 8⍴⍺
fn←{
⍝ a b c d to binary
a b c d←↓⍉(32⍴2)⊤⍵
⍝ a + F(b,c,d)
⍺<16:S[⍺]rot l[⍺]+2⊥a+d≠b∧c≠d
⍺<32:S[⍺]rot l[⍺]+2⊥a+(b∧d)∨(c∧~d)
⍺<48:S[⍺]rot l[⍺]+2⊥a+b≠c≠d
S[⍺]rot l[⍺]+2⊥a+c≠b∨~d
}
(2*32)|⍵+⊃{¯1⌽((⍵[1]+⍺ fn ⍵)@0)⍵}/(⌽⍳64),⊂⍵
}
⍝ process each 512 bits
loop←{⍬≡⍺:⍵ ⋄ (512↓⍺)∇(512↑⍺)proc ⍵}
⍝ output registers
(⎕D,⎕A)[,⍉(2⍴16)⊤,⍉⊖(4⍴256)⊤M loop A B C D]
}
Arturo
print digest "The quick brown fox jumped over the lazy dog's back"
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
ARM Assembly
/* ARM assembly Raspberry PI */
/* program MD5.s */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ LGHASH, 16 // result length
.equ ZWORKSIZE, 1000 // work area size
/*******************************************/
/* Structures */
/********************************************/
/* example structure variables */
.struct 0
var_a: // a
.struct var_a + 4
var_b: // b
.struct var_b + 4
var_c: // c
.struct var_c + 4
var_d: // d
.struct var_d + 4
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessTest1: .asciz "abc"
szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
szMessTest2: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz"
szMessFinPgm: .asciz "Program End ok.\n"
szMessResult: .asciz "Result for "
szMessResult1: .asciz " => "
szMessSizeError: .asciz "\033[31mWork area too small !! \033[0m \n"
szCarriageReturn: .asciz "\n"
.align 4
/* array constantes K */
tbConstK: .int 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee
.int 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501
.int 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be
.int 0x6b901122,0xfd987193,0xa679438e,0x49b40821
.int 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa
.int 0xd62f105d,0x2441453,0xd8a1e681,0xe7d3fbc8
.int 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed
.int 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a
.int 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c
.int 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70
.int 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x4881d05
.int 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665
.int 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039
.int 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1
.int 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1
.int 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
/* array rotation coef R */
tbRotaR: .int 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22
.int 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20
.int 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23
.int 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
tbConstH: .int 0x67452301 // H0
.int 0xEFCDAB89 // H1
.int 0x98BADCFE // H2
.int 0x10325476 // H3
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
tbH: .skip 4 * 4 @ 4 variables H
tbabcd: .skip 4 * 4 @ 4 variables a b c d
sZoneTrav: .skip 1000
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessTest1
bl computeExemple
ldr r0,iAdrszMessTest2
bl computeExemple
ldr r0,iAdrszMessTest3
bl computeExemple
ldr r0,iAdrszMessTest4
bl computeExemple
ldr r0,iAdrszMessFinPgm
bl affichageMess @ display message
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessResult: .int szMessResult
iAdrszMessResult1: .int szMessResult1
iAdrszMessTest1: .int szMessTest1
iAdrszMessTest2: .int szMessTest2
iAdrszMessTest3: .int szMessTest3
iAdrszMessTest4: .int szMessTest4
iAdrsZoneTrav: .int sZoneTrav
iAdrsZoneConv: .int sZoneConv
iAdrszMessFinPgm: .int szMessFinPgm
iAdrszMessSizeError: .int szMessSizeError
/***********************************************/
/* compute exemple */
/***********************************************/
/* r0 contains the address of the message */
computeExemple:
push {r1,lr} @ save registres
mov r1,r0
bl computeMD5 @ call routine MD5
ldr r0,iAdrszMessResult
bl affichageMess
mov r0,r1
bl affichageMess
ldr r0,iAdrszMessResult1
bl affichageMess
ldr r0, iAdrtbH
bl displayMD5
100:
pop {r1,pc} @ restaur registers
/******************************************************************/
/* compute MD5 */
/******************************************************************/
/* r0 contains the address of the message */
computeMD5:
push {r1-r12,lr} @ save registres
ldr r1,iAdrsZoneTrav
mov r2,#0 @ counter length
1: @ copy string in work area
cmp r2,#ZWORKSIZE @ maxi ?
bge 99f @ error
ldrb r3,[r0,r2]
strb r3,[r1,r2]
cmp r3,#0
addne r2,r2,#1
bne 1b
lsl r6,r2,#3 @ initial message length in bits
mov r3,#0b10000000 @ add bit 1 at end of string
strb r3,[r1,r2]
add r2,r2,#1 @ length in bytes
lsl r4,r2,#3 @ length in bits
mov r3,#0
2:
lsr r5,r2,#6
lsl r5,r5,#6
sub r5,r2,r5
cmp r5,#56
beq 3f @ yes -> end add
strb r3,[r1,r2] @ add zero at message end
add r2,#1 @ increment lenght bytes
add r4,#8 @ increment length in bits
b 2b
3:
str r6,[r1,r2] @ and store length at end
add r5,r2,#4
str r3,[r1,r5] @ store zero in hight bits for 64 bits
ldr r7,iAdrtbConstH @ constantes H address
ldr r4,iAdrtbH @ start area H
mov r5,#0
4: @ init array H with start constantes
ldr r6,[r7,r5,lsl #2] @ load constante
str r6,[r4,r5,lsl #2] @ and store
add r5,r5,#1
cmp r5,#4
blt 4b
@ split into block of 64 bytes
add r2,#4 @ TODO : à revoir
lsr r4,r2,#6 @ blocks number
ldr r0,iAdrtbH @ variables H
ldr r1,iAdrsZoneTrav
ldr r5,iAdrtbConstK
ldr r3,iAdrtbRotaR
ldr r8,iAdrtbabcd
mov r7,#0 @ n° de block et r1 contient l adresse zone de travail
5: @ begin loop of each block of 64 bytes
add r2,r1,r7,lsl #6 @ compute block begin indice * 4 * 16
mov r6,#0 @ indice t
/* COMPUTING THE MESSAGE DIGEST */
/* r0 variables H address */
/* r1 work area */
/* r2 block work area begin address */
/* r3 address constantes rotate */
/* r4 block number */
/* r5 constance K address */
/* r6 counter t */
/* r7 block counter */
/* r8 addresse variables a b c d */
@ init variable a b c d with variables H
mov r10,#0
6: @ loop init
ldr r9,[r0,r10,lsl #2] @ variables H
str r9,[r8,r10,lsl #2] @ variables a b c d
add r10,r10,#1
cmp r10,#4
blt 6b
7: @ loop begin
cmp r6,#15
bgt 8f
@ cas 1 f := (b et c) ou ((non b) et d)
@ g := i
ldr r9,[r8,#var_b]
ldr r10,[r8,#var_c]
and r12,r10,r9
mvn r9,r9
ldr r10,[r8,#var_d]
and r11,r9,r10
orr r12,r12,r11 @ f
mov r9,r6 @ g
b 11f
8:
cmp r6,#31
bgt 9f
@ f := (d et b) ou ((non d) et c)
@ g := (5×i + 1) mod 16
ldr r9,[r8,#var_b]
ldr r10,[r8,#var_d]
and r12,r10,r9
mvn r10,r10
ldr r9,[r8,#var_c]
and r11,r9,r10
orr r12,r12,r11 @ f
mov r9,#5
mul r9,r6,r9
add r9,r9,#1
lsr r10,r9,#4
lsl r10,r10,#4
sub r9,r9,r10 @ g
b 11f
9:
cmp r6,#47
bgt 10f
@ f := b xor c xor d
@ g := (3×i + 5) mod 16
ldr r9,[r8,#var_b]
ldr r10,[r8,#var_c]
eor r12,r10,r9
ldr r10,[r8,#var_d]
eor r12,r12,r10 @ f
mov r9,#3
mul r9,r6,r9
add r9,r9,#5
lsr r10,r9,#4
lsl r10,r10,#4
sub r9,r9,r10 @ g
b 11f
10:
@ f := c xor (b ou (non d))
@ g := (7×i) mod 16
ldr r10,[r8,#var_d]
mvn r12,r10
ldr r10,[r8,#var_b]
orr r12,r12,r10
ldr r10,[r8,#var_c]
eor r12,r12,r10 @ f
mov r9,#7
mul r9,r6,r9
lsr r10,r9,#4
lsl r10,r10,#4
sub r9,r9,r10 @ g
11:
ldr r10,[r8,#var_d]
mov r11,r10 @ save old d
ldr r10,[r8,#var_c]
str r10,[r8,#var_d] @ new d = c
ldr r10,[r8,#var_b]
str r10,[r8,#var_c] @ new c = b
ldr r10,[r8,#var_a]
add r12,r12,r10 @ a + f
ldr r10,[r2,r9,lsl #2]
add r12,r12,r10 @ + valeur bloc g
ldr r10,[r5,r6,lsl #2]
add r12,r12,r10 @ + valeur constante K de i
ldr r10,[r3,r6,lsl #2] @ rotate left value
rsb r10,r10,#32 @ compute right rotate
ror r12,r12,r10
ldr r10,[r8,#var_b]
add r12,r12,r10
str r12,[r8,#var_b] @ new b
str r11,[r8,#var_a] @ new a = old d
add r6,r6,#1
cmp r6,#63
ble 7b
@ maj area H
ldr r10,[r0] @ H0
ldr r11,[r8,#var_a]
add r10,r10,r11 @ + a
str r10,[r0]
ldr r10,[r0,#4] @ H1
ldr r11,[r8,#var_b]
add r10,r10,r11 @ + b
str r10,[r0,#4]
ldr r10,[r0,#8] @ H2
ldr r11,[r8,#var_c]
add r10,r10,r11 @ + c
str r10,[r0,#8]
ldr r10,[r0,#12] @ H3
ldr r11,[r8,#var_d]
add r10,r10,r11 @ + d
str r10,[r0,#12]
@ loop other block
add r7,r7,#1 @ increment block
cmp r7,r4 @ maxi ?
ble 5b
mov r9,#0 @ reverse bytes loop
12:
ldr r10,[r0,r9,lsl #2]
rev r10,r10 @ reverse bytes
str r10,[r0,r9,lsl #2]
add r9,r9,#1
cmp r9,#LGHASH / 4
blt 12b
mov r0,#0 @ routine OK
b 100f
99: @ size error
ldr r0,iAdrszMessSizeError
bl affichageMess
mov r0,#-1 @ error routine
100:
pop {r1-r12,pc} @ restaur registers
iAdrtbConstH: .int tbConstH
iAdrtbConstK: .int tbConstK
iAdrtbRotaR: .int tbRotaR
iAdrtbH: .int tbH
iAdrtbabcd: .int tbabcd
/*************************************************/
/* display hash MD5 */
/*************************************************/
/* r0 contains the address of hash */
displayMD5:
push {r1-r3,lr} @ save registres
mov r3,r0
mov r2,#0
1:
ldr r0,[r3,r2,lsl #2] @ load 4 bytes
ldr r1,iAdrsZoneConv
bl conversion16 @ conversion hexa
ldr r0,iAdrsZoneConv
bl affichageMess
add r2,r2,#1
cmp r2,#LGHASH / 4
blt 1b @ and loop
ldr r0,iAdrszCarriageReturn
bl affichageMess @ display message
100:
pop {r1-r3,lr} @ restaur registers
bx lr @ return
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
Result for abc => 900150983CD24FB0D6963F7D28E17F72 Result for ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 => D174AB98D277D9F5A5611C2C9F419D9F Result for abcdefghijklmnopqrstuvwxyz => C3FCD3D76192E4007DFB496CCA67E13B Result for 12345678901234567890123456789012345678901234567890123456789012345678901234567890 => 57EDF4A22BE3C955AC49DA2E2107B67A Program End ok.
AutoHotkey
Search autohotkey.com: [1]
Regular version
Source: AutoHotkey forum by SKAN
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
}
Native implementation
Source: AutoHotkey forum by Laszlo
; 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
}
BaCon
PRAGMA INCLUDE <stdio.h>
PRAGMA INCLUDE <stdlib.h>
PRAGMA INCLUDE <string.h>
PRAGMA INCLUDE <openssl/md5.h>
PRAGMA LDFLAGS -lcrypto -lm -w
DECLARE result TYPE unsigned char *
DECLARE string TYPE const char *
string = "Rosetta code"
strlenght = LEN(string)
result = MD5( string, strlenght , 0)
FOR i = 0 TO MD5_DIGEST_LENGTH-1
PRINT result[i] FORMAT "%02x"
NEXT
BASIC256
print MD5("")
print MD5("a")
print MD5("abc")
print MD5("message digest")
print MD5("abcdefghijklmnopqrstuvwxyz")
print MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
print MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
end
- Output:
d41d8cd98f00b204e9800998ecf8427e 0cc175b9c0f1b6a831c399e269772661 900150983cd24fb0d6963f7d28e17f72 f96b697d7cb7938d525a2f31aaf161d0 c3fcd3d76192e4007dfb496cca67e13b d174ab98d277d9f5a5611c2c9f419d9f 57edf4a22be3c955ac49da2e2107b67a
BBC BASIC
See MD5/Implementation for a native version.
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$
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;
}
Implementation of md5 (Needs review - differences observed for the last 8 characters when compared with openssl implementation)
#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;
}
C#
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());
C++
#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 ;
}
- Output:
The quick brown fox jumped over the lazy dog's back as a MD5 digest : e38ca1d920c4b8b8d3946b2c72f01680 !
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
(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"))))))
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. MD5.
AUTHOR. Bill Gunshannon
INSTALLATION. Home.
DATE-WRITTEN. 16 December 2021.
************************************************************
** Program Abstract:
** Use the md5sum utility and pass the HASH back using
** a temp file. Not elegant, but it works.
************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT Tmp-MD5 ASSIGN TO "/tmp/MD5"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD Tmp-MD5
DATA RECORD IS MD5-Rec.
01 MD5-Rec PIC X(32).
WORKING-STORAGE SECTION.
01 Eof PIC X VALUE 'F'.
01 Str1.
05 Pre-cmd PIC X(8)
VALUE 'echo -n '.
05 Str1-complete.
10 Str1-Part1 PIC X(26)
VALUE 'The quick brown fox jumps'.
10 Str1-Part2 PIC X(19)
VALUE ' over the lazy dog'.
05 Post-cmd PIC X(20)
VALUE ' | md5sum > /tmp/MD5'.
01 Str1-MD5 PIC X(32).
PROCEDURE DIVISION.
Main-Program.
DISPLAY Str1-complete.
PERFORM Get-MD5.
DISPLAY Str1-MD5.
STOP RUN.
Get-MD5.
CALL "SYSTEM" USING Str1.
OPEN INPUT Tmp-MD5.
READ Tmp-MD5 INTO Str1-MD5.
CLOSE Tmp-MD5.
CALL "CBL_DELETE_FILE" USING '/tmp/MD5'.
IDENTIFICATION DIVISION.
PROGRAM-ID. MD5-DEMO.
AUTHOR. Bill Gunshannon
INSTALLATION. Home.
DATE-WRITTEN. 16 December 2021.
************************************************************
** Program Abstract:
** Use the md5sum utility and pass the HASH back using
** a temp file. Not elegant, but it works.
** Same program but made MD5 a User Defined Function
** instead of a procedure.
************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION MD5.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Eof PIC X VALUE 'F'.
01 Str1.
05 Pre-cmd PIC X(8)
VALUE 'echo -n '.
05 Str1-complete.
10 Str1-Part1 PIC X(26)
VALUE 'The quick brown fox jumps'.
10 Str1-Part2 PIC X(19)
VALUE ' over the lazy dog'.
05 Post-cmd PIC X(20)
VALUE ' | md5sum > /tmp/MD5'.
01 Str1-MD5 PIC X(32).
PROCEDURE DIVISION.
Main-Program.
DISPLAY Str1-complete.
* PERFORM Get-MD5.
MOVE FUNCTION MD5(Str1) TO Str1-MD5.
DISPLAY Str1-MD5.
STOP RUN.
END PROGRAM MD5-DEMO.
IDENTIFICATION DIVISION.
FUNCTION-ID. MD5.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT Tmp-MD5 ASSIGN TO "/tmp/MD5"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD Tmp-MD5
DATA RECORD IS MD5-Rec.
01 MD5-Rec PIC X(32).
LINKAGE SECTION.
01 Str1 PIC X(128).
01 Str1-MD5 PIC X(32).
PROCEDURE DIVISION USING Str1 RETURNING Str1-MD5.
CALL "SYSTEM" USING FUNCTION TRIM(Str1).
OPEN INPUT Tmp-MD5.
READ Tmp-MD5 INTO Str1-MD5.
CLOSE Tmp-MD5.
CALL "CBL_DELETE_FILE" USING '/tmp/MD5'.
GO-BACK.
END FUNCTION MD5.
- Output:
The quick brown fox jumps over the lazy dog 9e107d9d372bb6826bd81d3542a419d6
Common 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)))
- Output:
"": d41d8cd98f00b204e9800998ecf8427e "a": 0cc175b9c0f1b6a831c399e269772661 "abc": 900150983cd24fb0d6963f7d28e17f72 "message digest": f96b697d7cb7938d525a2f31aaf161d0 "abcdefghijklmnopqrstuvwxyz": c3fcd3d76192e4007dfb496cca67e13b "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": d174ab98d277d9f5a5611c2c9f419d9f "12345678901234567890123456789012345678901234567890123456789012345678901234567890": 57edf4a22be3c955ac49da2e2107b67a
Another method using openssl:
(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))
- Output:
E38CA1D920C4B8B8D3946B2C72F01680
Crystal
require "digest/md5"
puts Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back")
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
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);
}
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Alternative version:
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());
}
}
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.
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.
Output:
D41D8CD98F00B204E9800998ECF8427E 0CC175B9C0F1B6A831C399E269772661 900150983CD24FB0D6963F7D28E17F72 F96B697D7CB7938D525A2F31AAF161D0 C3FCD3D76192E4007DFB496CCA67E13B D174AB98D277D9F5A5611C2C9F419D9F 57EDF4A22BE3C955AC49DA2E2107B67A
E
(with modifications)
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()
EasyLang
len md5k[] 64
proc md5init . .
for i = 1 to 64
md5k[i] = floor (0x100000000 * abs sin (i * 180 / pi))
.
.
md5init
#
func$ md5 inp$ .
subr addinp
if inp4 = 1
inp[] &= 0
.
inp[len inp[]] += b * inp4
inp4 *= 0x100
if inp4 = 0x100000000
inp4 = 1
.
.
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 ]
inp[] = [ ]
inp4 = 1
for i = 1 to len inp$
b = strcode substr inp$ i 1
addinp
.
b = 0x80
addinp
while len inp[] mod 16 <> 14 or inp4 <> 1
b = 0
addinp
.
h = len inp$ * 8
for i = 1 to 4
b = h mod 0x100
addinp
h = h div 0x100
.
inp[] &= 0
#
a0 = 0x67452301
b0 = 0xefcdab89
c0 = 0x98badcfe
d0 = 0x10325476
for chunk = 1 step 16 to len inp[] - 15
a = a0 ; b = b0 ; c = c0 ; d = d0
for i = 1 to 64
if i <= 16
h1 = bitand b c
h2 = bitand bitnot b d
f = bitor h1 h2
g = i - 1
elif i <= 32
h1 = bitand d b
h2 = bitand bitnot d c
f = bitor h1 h2
g = (5 * i - 4) mod 16
elif i <= 48
h1 = bitxor b c
f = bitxor h1 d
g = (3 * i + 2) mod 16
else
h1 = bitor b bitnot d
f = bitxor c h1
g = (7 * i - 7) mod 16
.
f = (f + a + md5k[i] + inp[chunk + g])
a = d
d = c
c = b
h1 = bitshift f s[i]
h2 = bitshift f (s[i] - 32)
b = (b + h1 + h2)
.
a0 += a ; b0 += b ; c0 += c ; d0 += d
.
for a in [ a0 b0 c0 d0 ]
for i = 1 to 4
b = a mod 256
a = a div 256
for h in [ b div 16 b mod 16 ]
h += 48
if h > 57
h += 39
.
s$ &= strchar h
.
.
.
return s$
.
#
print md5 "The quick brown fox jumped over the lazy dog's back"
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Emacs Lisp
(md5 "The quick brown fox jumped over the lazy dog's back") ;=> "e38ca1d920c4b8b8d3946b2c72f01680"
(secure-hash 'md5 "The quick brown fox jumped over the lazy dog's back") ;=> "e38ca1d920c4b8b8d3946b2c72f01680"
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:
-module(tests).
-export([md5/1]).
md5(S) ->
string:to_upper(
lists:flatten([io_lib:format("~2.16.0b",[N]) || <<N>> <= erlang:md5(S)])
).
Testing it:
1> c(tests).
{ok,tests}
2> tests:md5("The quick brown fox jumped over the lazy dog's back").
"E38CA1D920C4B8B8D3946B2C72F01680"
F#
Using built-in System.Security.Cryptography.MD5 class (Link to original blog [2]).
let md5ootb (msg: string) =
use md5 = System.Security.Cryptography.MD5.Create()
msg
|> System.Text.Encoding.ASCII.GetBytes
|> md5.ComputeHash
|> Seq.map (fun c -> c.ToString("X2"))
|> Seq.reduce ( + )
md5ootb @"The quick brown fox jumped over the lazy dog's back"
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
Fortran
Intel Fortran on Windows
Using Windows API. See CryptAcquireContextA, CryptCreateHash, CryptHashData and CryptGetHashParam in Microsoft documentation.
module md5_mod
use kernel32
use advapi32
implicit none
integer, parameter :: MD5LEN = 16
contains
subroutine md5hash(name, hash, dwStatus, filesize)
implicit none
character(*) :: name
integer, parameter :: BUFLEN = 32768
integer(HANDLE) :: hFile, hProv, hHash
integer(DWORD) :: dwStatus, nRead
integer(BOOL) :: status
integer(BYTE) :: buffer(BUFLEN)
integer(BYTE) :: hash(MD5LEN)
integer(UINT64) :: filesize
dwStatus = 0
filesize = 0
hFile = CreateFile(trim(name) // char(0), GENERIC_READ, FILE_SHARE_READ, NULL, &
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL)
if (hFile == INVALID_HANDLE_VALUE) then
dwStatus = GetLastError()
print *, "CreateFile failed."
return
end if
if (CryptAcquireContext(hProv, NULL, NULL, PROV_RSA_FULL, &
CRYPT_VERIFYCONTEXT) == FALSE) then
dwStatus = GetLastError()
print *, "CryptAcquireContext failed."
goto 3
end if
if (CryptCreateHash(hProv, CALG_MD5, 0_ULONG_PTR, 0_DWORD, hHash) == FALSE) then
dwStatus = GetLastError()
print *, "CryptCreateHash failed."
go to 2
end if
do
status = ReadFile(hFile, loc(buffer), BUFLEN, nRead, NULL)
if (status == FALSE .or. nRead == 0) exit
filesize = filesize + nRead
if (CryptHashData(hHash, buffer, nRead, 0) == FALSE) then
dwStatus = GetLastError()
print *, "CryptHashData failed."
go to 1
end if
end do
if (status == FALSE) then
dwStatus = GetLastError()
print *, "ReadFile failed."
go to 1
end if
nRead = MD5LEN
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, nRead, 0) == FALSE) then
dwStatus = GetLastError()
print *, "CryptGetHashParam failed.", status, nRead, dwStatus
end if
1 status = CryptDestroyHash(hHash)
2 status = CryptReleaseContext(hProv, 0)
3 status = CloseHandle(hFile)
end subroutine
end module
program md5
use md5_mod
implicit none
integer :: n, m, i, j
character(:), allocatable :: name
integer(DWORD) :: dwStatus
integer(BYTE) :: hash(MD5LEN)
integer(UINT64) :: filesize
n = command_argument_count()
do i = 1, n
call get_command_argument(i, length=m)
allocate(character(m) :: name)
call get_command_argument(i, name)
call md5hash(name, hash, dwStatus, filesize)
if (dwStatus == 0) then
do j = 1, MD5LEN
write(*, "(Z2.2)", advance="NO") hash(j)
end do
write(*, "(' ',A,' (',G0,' bytes)')") name, filesize
end if
deallocate(name)
end do
end program
FreeBASIC
See MD5/Implementation#FreeBASIC
Frink
The function messageDigest[string, hash]
returns a hex-encoded hash of any input string with a variety of hashing functions.
println[messageDigest["The quick brown fox", "MD5"]]
Futhark
Real languages roll their own crypto.
type md5 = (u32, u32, u32, u32)
fun rs(): [64]u32 =
map u32
([ 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 ])
fun ks(): [64]u32 =
map u32
([ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 ])
fun md5(ms: [n][16]u32): md5 =
let a0 = u32(0x67452301)
let b0 = u32(0xefcdab89)
let c0 = u32(0x98badcfe)
let d0 = u32(0x10325476)
loop ((a0,b0,c0,d0)) = for i < n do
let (a,b,c,d) = md5_chunk (a0,b0,c0,d0) ms[i]
in (a0+a, b0+b, c0+c, d0+d)
in (a0,b0,c0,d0)
fun rotate_left(x: u32, c: u32): u32 = (x << c) | (x >> (32u32 - c))
fun bytes(x: u32): [4]u8 = [u8(x),
u8(x/0x100u32),
u8(x/0x10000u32),
u8(x/0x1000000u32)]
fun unbytes(bs: [4]u8): u32 =
u32(bs[0]) +
u32(bs[1]) * 0x100u32 +
u32(bs[2]) * 0x10000u32 +
u32(bs[3]) * 0x1000000u32
fun unbytes_block(block: [64]u8): [16]u32 =
map unbytes (reshape (16,4) block)
fun main(ms: [n]u8): [16]u8 =
let padding = 64 - (n % 64)
let n_padded = n + padding
let ms_padded = concat ms (bytes 0x80u32) (replicate (padding-12) 0x0u8) (bytes (u32(n*8))) ([0u8,0u8,0u8,0u8])
let (a,b,c,d) = md5 (map unbytes_block (reshape (n_padded / 64, 64) ms_padded))
in reshape 16 (map bytes ([a,b,c,d]))
-- Process 512 bits of the input.
fun md5_chunk ((a0,b0,c0,d0): md5) (m: [16]u32): md5 =
loop ((a,b,c,d) = (a0,b0,c0,d0)) = for i < 64 do
let (f,g) =
if i < 16 then ((b & c) | ((~b) & d),
i)
else if i < 32 then ((d & b) | ((~d) & c),
i32((5u32*u32(i) + 1u32) % 16u32))
else if i < 48 then (b ^ c ^ d,
i32((3u32*u32(i) + 5u32) % 16u32))
else (c ^ (b | (~d)),
i32((7u32*u32(i)) % 16u32))
in (d, b + rotate_left(a + f + (ks())[i] + m[g], (rs())[i]), b, c)
in (a,b,c,d)
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)
}
}
Groovy
import java.security.MessageDigest
String.metaClass.md5Checksum = {
MessageDigest.getInstance('md5').digest(delegate.bytes).collect { String.format("%02x", it) }.join('')
}
Testing
assert 'The quick brown fox jumps over the lazy dog'.md5Checksum() == '9e107d9d372bb6826bd81d3542a419d6'
Haskell
Use modules nano-MD5 and ByteString from HackageDB
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
Use in GHCi:
*Main> main e38ca1d920c4b8b8d3946b2c72f01680
This version uses the Cryptonite package:
#!/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
- Output:
$ ./md5.hs The quick brown fox jumped over the lazy dog\'s back e38ca1d920c4b8b8d3946b2c72f01680
Haxe
import haxe.crypto.Md5;
class Main {
static function main() {
var md5 = Md5.encode("The quick brown fox jumped over the lazy dog's back");
Sys.println(md5);
}
}
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
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.
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
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
J
Using the md5 script from the convert/misc addon package:
require 'convert/misc/md5'
md5 'The quick brown fox jumped over the lazy dog''s back'
e38ca1d920c4b8b8d3946b2c72f01680
Implementation here, in case the link to the script goes dead again:
require 'convert'
'`lt gt ge xor'=: (20 b.)`(18 b.)`(27 b.)`(22 b.)
'`and or sh'=: (17 b.)`(23 b.)`(33 b.)
{{
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=: {{
'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{{)n
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{{)n
_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=: {{
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
}}
md5=: {{
X=. norm y
q=. r=. 1732584193 _271733879 _1732584194 271733878
for_k. X do.
for_j. i.4 do.
l=. ((j{I){k) ,. (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
}}
An alternative and faster approach is to use the Qt library function available using the ide/qt addon from J8:
require '~addons/ide/qt/qt.ijs'
getmd5=: 'md5'&gethash_jqtide_
getmd5 'The quick brown fox jumped over the lazy dog''s back'
e38ca1d920c4b8b8d3946b2c72f01680
Java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Digester {
public static void main(String[] args) {
System.out.println(hexDigest("Rosetta code", "MD5"));
}
static String hexDigest(String str, String digestName) {
try {
MessageDigest md = MessageDigest.getInstance(digestName);
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
char[] hex = new char[digest.length * 2];
for (int i = 0; i < digest.length; i++) {
hex[2 * i] = "0123456789abcdef".charAt((digest[i] & 0xf0) >> 4);
hex[2 * i + 1] = "0123456789abcdef".charAt(digest[i] & 0x0f);
}
return new String(hex);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
}
}
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 "UTF_8" in the example above) are available from the Charset and StandardCharsets classes.
Jsish
/* MD5 hash in Jsish */
var str = 'Rosetta code';
puts(Util.hash(str, {type:'md5'}));
/* MD5 RFC1321 test suite */
function MD5(str) { return Util.hash(str, {type:'md5'}); }
;MD5('');
;MD5('a');
;MD5('abc');
;MD5('message digest');
;MD5('abcdefghijklmnopqrstuvwxyz');
;MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
;MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890');
/*
=!EXPECTSTART!=
bf0ac9c7e94e9d50c18f4ff592643546
MD5('') ==> d41d8cd98f00b204e9800998ecf8427e
MD5('a') ==> 0cc175b9c0f1b6a831c399e269772661
MD5('abc') ==> 900150983cd24fb0d6963f7d28e17f72
MD5('message digest') ==> f96b697d7cb7938d525a2f31aaf161d0
MD5('abcdefghijklmnopqrstuvwxyz') ==> c3fcd3d76192e4007dfb496cca67e13b
MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') ==> d174ab98d277d9f5a5611c2c9f419d9f
MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') ==> 57edf4a22be3c955ac49da2e2107b67a
=!EXPECTEND!=
*/
- Output:
prompt$ jsish md5.jsi bf0ac9c7e94e9d50c18f4ff592643546 prompt$ jsish --U md5.jsi # display unit test echos bf0ac9c7e94e9d50c18f4ff592643546 MD5('') ==> d41d8cd98f00b204e9800998ecf8427e MD5('a') ==> 0cc175b9c0f1b6a831c399e269772661 MD5('abc') ==> 900150983cd24fb0d6963f7d28e17f72 MD5('message digest') ==> f96b697d7cb7938d525a2f31aaf161d0 MD5('abcdefghijklmnopqrstuvwxyz') ==> c3fcd3d76192e4007dfb496cca67e13b MD5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') ==> d174ab98d277d9f5a5611c2c9f419d9f MD5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') ==> 57edf4a22be3c955ac49da2e2107b67a prompt$ jsish -u md5.jsi # run the unit tests [PASS] md5.jsi
Julia
using Nettle
function Base.trunc(s::AbstractString, n::Integer)
n > 0 || throw(DomainError())
l = length(s)
l > n || return s
n > 3 || 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, h) in sort(tests, by = length ∘ first)
md5sum = hexdigest("md5", k)
@printf("%20s → %s ", trunc(k, 15), md5sum)
if md5sum == h
println("MD5 OK")
else
println("MD5 Bad")
println("* The sum should be ", h)
end
end
- Output:
→ 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 O
Kotlin
// version 1.0.6
import java.security.MessageDigest
fun main(args: Array<String>) {
val text = "The quick brown fox jumped over the lazy dog's back"
val bytes = text.toByteArray()
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(bytes)
for (byte in digest) print("%02x".format(byte))
println()
}
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Lasso
Encrypt_MD5('Welcome all Rhinos!')
//80ba88ee2600e9e9b36e739458c39ebd
Test suite
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'
^}
- Output:
testing: "12345678901234567890123456789012345678901234567890123456789012345678901234567890": true testing: "a": true testing: "abc": true testing: "abcdefghijklmnopqrstuvwxyz": true testing: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": true testing: "message digest": true
Liberty BASIC
'[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
Lingo
- Using a binary plugin ("Xtra"):
put cx_md5_string(str)
- Pure Lingo implementation
----------------------------------------
-- Calculates MD5 hash of string or bytearray
-- @param {bytearray|string} input
-- @return {bytearray} (16 bytes)
----------------------------------------
on md5 (input)
if stringP(input) then input = bytearray(input)
-- Convert string to list of little-endian words...
t_iLen = input.length * 8
t_iCnt = (t_iLen + 64) / 512 * 16 + 16
-- Create list, fill with zeros...
x = []
x[t_iCnt] = 0
t_fArr = [1, 256, 65536, 16777216]
i = 0
j = 0
repeat while i < t_iLen
j = j + 1
t_iNext = i / 32 + 1
t_iTemp = bitAnd(input[i/8+1], 255) * t_fArr[j]
x[t_iNext] = bitOr(x[t_iNext], t_iTemp)
i = i + 8
j = j mod 4
end repeat
-- Append padding...
t_iNext = t_iLen / 32 + 1
x[t_iNext] = bitOr(x[t_iNext], 128 * t_fArr[j + 1])
x[(t_iLen + 64) / 512 * 16 + 15] = t_iLen
-- Actual algorithm starts here...
a = 1732584193
b = -271733879
c = -1732584194
d = 271733878
i = 1
t_iWrap = the maxInteger + 1
t_iCount = x.count + 1
repeat while i < t_iCount
olda = a
oldb = b
oldc = c
oldd = d
-- Round(1) --
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i] - 680876936
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b
else a = bitOr(n * 128, n / 33554432) + b
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 1] - 389564586
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a
else d = bitOr(n * 4096, n / 1048576) + a
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 2] + 606105819
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d
else c = bitOr(n * 131072, n / 32768) + d
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 3] - 1044525330
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c
else b = bitOr(n * 4194304, n / 1024) + c
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 4] - 176418897
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b
else a = bitOr(n * 128, n / 33554432) + b
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 5] + 1200080426
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a
else d = bitOr(n * 4096, n / 1048576) + a
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 6] - 1473231341
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d
else c = bitOr(n * 131072, n / 32768) + d
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 7] - 45705983
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c
else b = bitOr(n * 4194304, n / 1024) + c
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 8] + 1770035416
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b
else a = bitOr(n * 128, n / 33554432) + b
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 9] - 1958414417
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a
else d = bitOr(n * 4096, n / 1048576) + a
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 10] - 42063
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d
else c = bitOr(n * 131072, n / 32768) + d
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 11] - 1990404162
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c
else b = bitOr(n * 4194304, n / 1024) + c
n = bitOr(bitAnd(b, c), bitAnd(bitNot(b), d)) + a + x[i + 12] + 1804603682
if(n < 0) then a = bitOr(n * 128, bitOr((n + t_iWrap) / 33554432, 64)) + b
else a = bitOr(n * 128, n / 33554432) + b
n = bitOr(bitAnd(a, b), bitAnd(bitNot(a), c)) + d + x[i + 13] - 40341101
if(n < 0) then d = bitOr(n * 4096, bitOr((n + t_iWrap) / 1048576, 2048)) + a
else d = bitOr(n * 4096, n / 1048576) + a
n = bitOr(bitAnd(d, a), bitAnd(bitNot(d), b)) + c + x[i + 14] - 1502002290
if(n < 0) then c = bitOr(n * 131072, bitOr((n + t_iWrap) / 32768, 65536)) + d
else c = bitOr(n * 131072, n / 32768) + d
n = bitOr(bitAnd(c, d), bitAnd(bitNot(c), a)) + b + x[i + 15] + 1236535329
if(n < 0) then b = bitOr(n * 4194304, bitOr((n + t_iWrap) / 1024, 2097152)) + c
else b = bitOr(n * 4194304, n / 1024) + c
-- Round(2) --
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 1] - 165796510
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b
else a = bitOr(n * 32, n / 134217728) + b
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 6] - 1069501632
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a
else d = bitOr(n * 512, n / 8388608) + a
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 11] + 643717713
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d
else c = bitOr(n * 16384, n / 262144) + d
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i] - 373897302
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c
else b = bitOr(n * 1048576, n / 4096) + c
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 5] - 701558691
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b
else a = bitOr(n * 32, n / 134217728) + b
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 10] + 38016083
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a
else d = bitOr(n * 512, n / 8388608) + a
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 15] - 660478335
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d
else c = bitOr(n * 16384, n / 262144) + d
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 4] - 405537848
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c
else b = bitOr(n * 1048576, n / 4096) + c
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 9] + 568446438
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b
else a = bitOr(n * 32, n / 134217728) + b
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 14] - 1019803690
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a
else d = bitOr(n * 512, n / 8388608) + a
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 3] - 187363961
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d
else c = bitOr(n * 16384, n / 262144) + d
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 8] + 1163531501
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c
else b = bitOr(n * 1048576, n / 4096) + c
n = bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + a + x[i + 13] - 1444681467
if(n < 0) then a = bitOr(n * 32, bitOr((n + t_iWrap) / 134217728, 16)) + b
else a = bitOr(n * 32, n / 134217728) + b
n = bitOr(bitAnd(a, c), bitAnd(b, bitNot(c))) + d + x[i + 2] - 51403784
if(n < 0) then d = bitOr(n * 512, bitOr((n + t_iWrap) / 8388608, 256)) + a
else d = bitOr(n * 512, n / 8388608) + a
n = bitOr(bitAnd(d, b), bitAnd(a, bitNot(b))) + c + x[i + 7] + 1735328473
if(n < 0) then c = bitOr(n * 16384, bitOr((n + t_iWrap) / 262144, 8192)) + d
else c = bitOr(n * 16384, n / 262144) + d
n = bitOr(bitAnd(c, a), bitAnd(d, bitNot(a))) + b + x[i + 12] - 1926607734
if(n < 0) then b = bitOr(n * 1048576, bitOr((n + t_iWrap) / 4096, 524288)) + c
else b = bitOr(n * 1048576, n / 4096) + c
-- Round(3) --
n = bitXor(bitXor(b, c), d) + a + x[i + 5] - 378558
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b
else a = bitOr(n * 16, n / 268435456) + b
n = bitXor(bitXor(a, b), c) + d + x[i + 8] - 2022574463
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a
else d = bitOr(n * 2048, n / 2097152) + a
n = bitXor(bitXor(d, a), b) + c + x[i + 11] + 1839030562
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d
else c = bitOr(n * 65536, n / 65536) + d
n = bitXor(bitXor(c, d), a) + b + x[i + 14] - 35309556
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c
else b = bitOr(n * 8388608, n / 512) + c
n = bitXor(bitXor(b, c), d) + a + x[i + 1] - 1530992060
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b
else a = bitOr(n * 16, n / 268435456) + b
n = bitXor(bitXor(a, b), c) + d + x[i + 4] + 1272893353
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a
else d = bitOr(n * 2048, n / 2097152) + a
n = bitXor(bitXor(d, a), b) + c + x[i + 7] - 155497632
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d
else c = bitOr(n * 65536, n / 65536) + d
n = bitXor(bitXor(c, d), a) + b + x[i + 10] - 1094730640
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c
else b = bitOr(n * 8388608, n / 512) + c
n = bitXor(bitXor(b, c), d) + a + x[i + 13] + 681279174
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b
else a = bitOr(n * 16, n / 268435456) + b
n = bitXor(bitXor(a, b), c) + d + x[i] - 358537222
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a
else d = bitOr(n * 2048, n / 2097152) + a
n = bitXor(bitXor(d, a), b) + c + x[i + 3] - 722521979
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d
else c = bitOr(n * 65536, n / 65536) + d
n = bitXor(bitXor(c, d), a) + b + x[i + 6] + 76029189
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c
else b = bitOr(n * 8388608, n / 512) + c
n = bitXor(bitXor(b, c), d) + a + x[i + 9] - 640364487
if(n < 0) then a = bitOr(n * 16, bitOr((n + t_iWrap) / 268435456, 8)) + b
else a = bitOr(n * 16, n / 268435456) + b
n = bitXor(bitXor(a, b), c) + d + x[i + 12] - 421815835
if(n < 0) then d = bitOr(n * 2048, bitOr((n + t_iWrap) / 2097152, 1024)) + a
else d = bitOr(n * 2048, n / 2097152) + a
n = bitXor(bitXor(d, a), b) + c + x[i + 15] + 530742520
if(n < 0) then c = bitOr(n * 65536, bitOr((n + t_iWrap) / 65536, 32768)) + d
else c = bitOr(n * 65536, n / 65536) + d
n = bitXor(bitXor(c, d), a) + b + x[i + 2] - 995338651
if(n < 0) then b = bitOr(n * 8388608, bitOr((n + t_iWrap) / 512, 4194304)) + c
else b = bitOr(n * 8388608, n / 512) + c
-- Round(4) --
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i] - 198630844
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b
else a = bitOr(n * 64, n / 67108864) + b
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 7] + 1126891415
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a
else d = bitOr(n * 1024, n / 4194304) + a
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 14] - 1416354905
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d
else c = bitOr(n * 32768, n / 131072) + d
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 5] - 57434055
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c
else b = bitOr(n * 2097152, n / 2048) + c
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 12] + 1700485571
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b
else a = bitOr(n * 64, n / 67108864) + b
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 3] - 1894986606
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a
else d = bitOr(n * 1024, n / 4194304) + a
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 10] - 1051523
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d
else c = bitOr(n * 32768, n / 131072) + d
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 1] - 2054922799
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c
else b = bitOr(n * 2097152, n / 2048) + c
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 8] + 1873313359
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b
else a = bitOr(n * 64, n / 67108864) + b
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 15] - 30611744
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a
else d = bitOr(n * 1024, n / 4194304) + a
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 6] - 1560198380
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d
else c = bitOr(n * 32768, n / 131072) + d
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 13] + 1309151649
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c
else b = bitOr(n * 2097152, n / 2048) + c
n = bitXor(c, bitOr(b, bitNot(d))) + a + x[i + 4] - 145523070
if(n < 0) then a = bitOr(n * 64, bitOr((n + t_iWrap) / 67108864, 32)) + b
else a = bitOr(n * 64, n / 67108864) + b
n = bitXor(b, bitOr(a, bitNot(c))) + d + x[i + 11] - 1120210379
if(n < 0) then d = bitOr(n * 1024, bitOr((n + t_iWrap) / 4194304, 512)) + a
else d = bitOr(n * 1024, n / 4194304) + a
n = bitXor(a, bitOr(d, bitNot(b))) + c + x[i + 2] + 718787259
if(n < 0) then c = bitOr(n * 32768, bitOr((n + t_iWrap) / 131072, 16384)) + d
else c = bitOr(n * 32768, n / 131072) + d
n = bitXor(d, bitOr(c, bitNot(a))) + b + x[i + 9] - 343485551
if(n < 0) then b = bitOr(n * 2097152, bitOr((n + t_iWrap) / 2048, 1048576)) + c
else b = bitOr(n * 2097152, n / 2048) + c
a = a + olda
b = b + oldb
c = c + oldc
d = d + oldd
i = i + 16
end repeat
t_iArr = [a, b, c, d]
ba = bytearray()
p = 1
repeat with i in t_iArr
if(i > 0) then
repeat with n = 1 to 4
ba[p] = (i mod 256)
i = i / 256
p = p+1
end repeat
else
i = bitNot(i)
repeat with n = 1 to 4
ba[p] = 255-(i mod 256)
i = i / 256
p = p+1
end repeat
end if
end repeat
ba.position = 1
return ba
end
LiveCode
Livecode has built-in support for md4 and md5
function md5sum hashtext
local md5, mdhex
put md5Digest(hashtext) into md5
get binaryDecode("H*",md5,mdhex)
return mdhex
end md5sum
Tests
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
Output
ok abc ok abclower ok 123 ok abcupper ok message digest ok a ok empty
Lua
Using the Kepler MD5 library:
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")
Maple
The Hash command in the StringTools package computes the MD5 hash value of a string.
> with( StringTools ):
> Hash( "" );
"d41d8cd98f00b204e9800998ecf8427e"
> Hash( "a" );
"0cc175b9c0f1b6a831c399e269772661"
> Hash( "abc" );
"900150983cd24fb0d6963f7d28e17f72"
> Hash( "message digest" );
"f96b697d7cb7938d525a2f31aaf161d0"
> Hash( "abcdefghijklmnopqrstuvwxyz" );
"c3fcd3d76192e4007dfb496cca67e13b"
> Hash( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" );
"d174ab98d277d9f5a5611c2c9f419d9f"
> Hash( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" );
"57edf4a22be3c955ac49da2e2107b67a"
Mathematica /Wolfram Language
Mathematica has built-in functions Hash and FileHash. Example:
Hash["The quick brown fox jumped over the lazy dog's back","MD5","HexString"]
gives back:
e38ca1d920c4b8b8d3946b2c72f01680
MATLAB
This code also works with Octave (but Octave already provides md5sum(), see Octave example).
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
Sample Usage:
octave:14> md5('Rosetta Code')
ans = CCA1BF66B09554E10F837838C3D3EFB1
min
"The quick brown fox jumps over the lazy dog" md5 puts!
MOO
string = "The quick brown fox jumped over the lazy dog's back";
player:tell(string_hash(string));
Neko
/**
MD5 in Neko
Tectonics:
nekoc md5.neko
neko md5
*/
var MD5 = $loader.loadprim("std@make_md5", 1);
var base_encode = $loader.loadprim("std@base_encode", 2);
var result = MD5("The quick brown fox jumps over the lazy dog");
/* Output in lowercase hex */
$print(base_encode(result, "0123456789abcdef"));
- Output:
prompt$ nekoc md5.neko prompt$ neko md5.n 9e107d9d372bb6826bd81d3542a419d6
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)) ");
}
}
Output:
True True True True True True True True
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
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
;; 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")
Nim
import md5
echo toMD5("The quick brown fox jumped over the lazy dog's back")
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Nu
[
'' 'a' 'abc' 'message digest'
'abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
]
| each { hash md5 }
- Output:
╭───┬──────────────────────────────────╮ │ 0 │ d41d8cd98f00b204e9800998ecf8427e │ │ 1 │ 0cc175b9c0f1b6a831c399e269772661 │ │ 2 │ 900150983cd24fb0d6963f7d28e17f72 │ │ 3 │ f96b697d7cb7938d525a2f31aaf161d0 │ │ 4 │ c3fcd3d76192e4007dfb496cca67e13b │ │ 5 │ d174ab98d277d9f5a5611c2c9f419d9f │ │ 6 │ 57edf4a22be3c955ac49da2e2107b67a │ ╰───┴──────────────────────────────────╯
Oberon-2
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.
- Output:
MD5: E38CA1D9 20C4B8B8 D3946B2C 72F01680
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();
}
}
Objective-C
only; not Cocoa
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]);
#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);
}
(need to include "libcrypto.dylib" framework)
#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);
}
OCaml
# Digest.to_hex(Digest.string "The quick brown fox jumped over the lazy dog's back") ;;
- : string = "e38ca1d920c4b8b8d3946b2c72f01680"
Octave
s = "The quick brown fox jumped over the lazy dog's back";
hash = md5sum(s, true);
disp(hash)
For an implementation of MD5, see MATLAB example.
Ol
(import (otus ffi))
(define libcrypto (load-dynamic-library "libcrypto.so.1.0.0"))
(define MD5 (libcrypto type-vptr "MD5" type-string fft-unsigned-long type-string))
- Output:
(define (test str)
(define md5 "----------------")
(MD5 str (string-length str) md5)
(for-each display (list "\"" str "\": "))
(for-each (lambda (c)
(define hex "0123456789abcdef")
(display (string (ref hex (>> c 4))))
(display (string (ref hex (band c #x0F)))))
(string->list md5))
(print))
(test "")
(test "a")
(test "abc")
(test "message digest")
(test "abcdefghijklmnopqrstuvwxyz")
(test "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
(test "12345678901234567890123456789012345678901234567890123456789012345678901234567890")
"": d41d8cd98f00b204e9800998ecf8427e "a": 0cc175b9c0f1b6a831c399e269772661 "abc": 900150983cd24fb0d6963f7d28e17f72 "message digest": f96b697d7cb7938d525a2f31aaf161d0 "abcdefghijklmnopqrstuvwxyz": c3fcd3d76192e4007dfb496cca67e13b "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": d174ab98d277d9f5a5611c2c9f419d9f "12345678901234567890123456789012345678901234567890123456789012345678901234567890": 57edf4a22be3c955ac49da2e2107b67a
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.
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
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)
#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);
}
Compile with: gcc -Wall -O2 -fPIC -shared md5.c -o libmd5.so -lcrypt -lpari
Load plugin from your home directory into PARI:
install("plug_md5", "s", "MD5", "~/libmd5.so");
MD5("The quick brown fox jumped over the lazy dog's back")
Output:
"e38ca1d920c4b8b8d3946b2c72f01680"
Here is an explicit implementation in the PARI/GP language:
md5( message ) = { my(
a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476,
s = [ 7, 12, 17, 22; 5, 9, 14, 20; 4, 11, 16, 23; 6, 10, 15, 21 ],
msg = concat( Vec( concat(Vecsmall(message), Vecsmall(128)), (#message + 9) \ 64 * 64 + 56 ),
Vecrev(digits( #message % 2^61 * 8, 256), 8)), \\ little endian !
leftrotate(x, c) = x << c + x >> (32-c)
);
\\*** Process the message in successive 512-bit chunks ***
forstep( m=1, #msg, 512/8,
my( \\ break chunk into 32-bit words M[j] - LITTLE ENDIAN !
M = vector( 16, j, fromdigits( Vecrev(msg[ m + j*4 - 4 .. m + j*4 - 1 ]), 2^8 )),
A = a, B = b, C = c, D = d);
for( i = 0 , 63 , [A, D, C, B] = [D, C, B, B + leftrotate( ( A + abs(sin(i+1))\2^-32 +
if( i < 16 , bitor( bitand(B , C) , bitand( bitneg(B) , D)) + M[ i +1]
, i < 32 , bitor( bitand(D , B) , bitand( bitneg(D) , C)) + M[ (5*i + 1) % 16 +1]
, i < 48 , bitxor( bitxor( B , C ) , D ) + M[ (3*i + 5) % 16 +1]
, bitxor( C , bitor( bitneg(D), B)) + M[ 7*i % 16 +1]
)) % 2^32, s[i\16+1, i%4+1] )]
); \\ end for
[a,b,c,d] = ([a,b,c,d] + [A,B,C,D]) % 2^32 ;
); \\ end forstep
Strprintf("%032x",fromdigits(Vecrev(digits(fromdigits([d,c,b,a],2^32),256),16),256))
}
Then:
gp > md5("")
%2 = "d41d8cd98f00b204e9800998ecf8427e"
gp > md5("The quick brown fox jumps over lazy dogs.")
%3 = "4c57070257998981a0c7b7ec003b9d5c"
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);
end.
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
To digest a file, use md5Print(md5File('myfile.txt')) where myfile.txt is a file.
Perl
use Digest::MD5 qw(md5_hex);
print md5_hex("The quick brown fox jumped over the lazy dog's back"), "\n";
The same in OO manner
use Digest::MD5;
$md5 = Digest::MD5->new;
$md5->add("The quick brown fox jumped over the lazy dog's back");
print $md5->hexdigest, "\n";
Phix
PHP
$string = "The quick brown fox jumped over the lazy dog's back";
echo md5( $string );
PicoLisp
Using the openssl library (the 'native' function is only in the 64-bit version available):
(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))) ) ) )
Output:
-> "E38CA1D920C4B8B8D3946B2C72F01680"
Pike
import String;
import Crypto.MD5;
int main(){
write( string2hex( hash( "The quick brown fox jumped over the lazy dog's back" ) ) + "\n" );
}
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()
PureBasic
- Purebasic 5.x versions
UseMD5Fingerprint() ; register the MD5 fingerprint plugin
test$ = "The quick brown fox jumped over the lazy dog's back"
; Call StringFingerprint() function and display MD5 result in Debug window
Debug StringFingerprint(test$, #PB_Cipher_MD5)
Python
Using builtin libraries:
- Python 3.x, 2.5 and later 2.x versions
>>> 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
>>>
- Python 2.5 and later
>>> import hashlib
>>> print hashlib.md5("The quick brown fox jumped over the lazy dog's back").hexdigest()
e38ca1d920c4b8b8d3946b2c72f01680
- Pre-2.5; removed in 3.x
>>> import md5
>>> print md5.md5("The quick brown fox jumped over the lazy dog's back").hexdigest()
e38ca1d920c4b8b8d3946b2c72f01680
R
library(digest)
hexdigest <- digest("The quick brown fox jumped over the lazy dog's back",
algo="md5", serialize=FALSE)
Racket
#lang racket
(require file/md5)
(md5 "")
(md5 "a")
(md5 "abc")
(md5 "message digest")
(md5 "abcdefghijklmnopqrstuvwxyz")
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890")
Output:
#"d41d8cd98f00b204e9800998ecf8427e" #"0cc175b9c0f1b6a831c399e269772661" #"900150983cd24fb0d6963f7d28e17f72" #"f96b697d7cb7938d525a2f31aaf161d0" #"c3fcd3d76192e4007dfb496cca67e13b" #"d174ab98d277d9f5a5611c2c9f419d9f" #"57edf4a22be3c955ac49da2e2107b67a"
Raku
(formerly Perl 6) Library Digest::MD5
use Digest::MD5;
say Digest::MD5.md5_hex: "The quick brown fox jumped over the lazy dog's back";
REBOL
>> checksum/method "The quick brown fox jumped over the lazy dog" 'md5
== #{08A008A01D498C404B0C30852B39D3B8}
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*/ /*────step────*/
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)
output when using the default (internal) inputs:
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
Ring
See MD5("my string!") + nl
# output : a83a049fbe50cf7334caa86bf16a3520
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.
>> 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
RPG
Modified from [3]:
**FREE
Ctl-opt MAIN(Main);
Ctl-opt DFTACTGRP(*NO) ACTGRP(*NEW);
dcl-pr QDCXLATE EXTPGM('QDCXLATE');
dataLen packed(5 : 0) CONST;
data char(32767) options(*VARSIZE);
conversionTable char(10) CONST;
end-pr;
dcl-pr Qc3CalculateHash EXTPROC('Qc3CalculateHash');
inputData pointer value;
inputDataLen int(10) const;
inputDataFormat char(8) const;
algorithmDscr char(16) const;
algorithmFormat char(8) const;
cryptoServiceProvider char(1) const;
cryptoDeviceName char(1) const options(*OMIT);
hash char(64) options(*VARSIZE : *OMIT);
errorCode char(32767) options(*VARSIZE);
end-pr;
dcl-c HEX_CHARS CONST('0123456789ABCDEF');
dcl-proc Main;
dcl-s inputData char(45);
dcl-s inputDataLen int(10) INZ(0);
dcl-s outputHash char(16);
dcl-s outputHashHex char(32);
dcl-ds algorithmDscr QUALIFIED;
hashAlgorithm int(10) INZ(0);
end-ds;
dcl-ds ERRC0100_NULL QUALIFIED;
bytesProvided int(10) INZ(0); // Leave at zero
bytesAvailable int(10);
end-ds;
dow inputDataLen = 0;
DSPLY 'Input: ' '' inputData;
inputData = %trim(inputData);
inputDataLen = %len(%trim(inputData));
DSPLY ('Input=' + inputData);
DSPLY ('InputLen=' + %char(inputDataLen));
if inputDataLen = 0;
DSPLY 'Input must not be blank';
endif;
enddo;
// Convert from EBCDIC to ASCII
QDCXLATE(inputDataLen : inputData : 'QTCPASC');
algorithmDscr.hashAlgorithm = 1; // MD5
// Calculate hash
Qc3CalculateHash(%addr(inputData) : inputDataLen : 'DATA0100' : algorithmDscr
: 'ALGD0500' : '0' : *OMIT : outputHash : ERRC0100_NULL);
// Convert to hex
CVTHC(outputHashHex : outputHash : 32);
DSPLY ('MD5: ' + outputHashHex);
return;
end-proc;
// This procedure is actually a MI, but I couldn't get it to bind so I wrote my own version
dcl-proc CVTHC;
dcl-pi *N;
target char(65534) options(*VARSIZE);
srcBits char(32767) options(*VARSIZE) CONST;
targetLen int(10) value;
end-pi;
dcl-s i int(10);
dcl-s lowNibble ind INZ(*OFF);
dcl-s inputOffset int(10) INZ(1);
dcl-ds dataStruct QUALIFIED;
numField int(5) INZ(0);
// IBM i is big-endian
charField char(1) OVERLAY(numField : 2);
end-ds;
for i = 1 to targetLen;
if lowNibble;
dataStruct.charField = %BitAnd(%subst(srcBits : inputOffset : 1) : X'0F');
inputOffset += 1;
else;
dataStruct.charField = %BitAnd(%subst(srcBits : inputOffset : 1) : X'F0');
dataStruct.numField /= 16;
endif;
%subst(target : i : 1) = %subst(HEX_CHARS : dataStruct.numField + 1 : 1);
lowNibble = NOT lowNibble;
endfor;
return;
end-proc;
Note that this implementation converts the input from EBCDIC to ASCII before computing the hash.
Sample output:
DSPLY Input: abcdefghijklmnopqrstuvwxyz DSPLY Input=abcdefghijklmnopqrstuvwxyz DSPLY InputLen=26 DSPLY MD5: C3FCD3D76192E4007DFB496CCA67E13B
Ruby
require 'digest'
Digest::MD5.hexdigest("The quick brown fox jumped over the lazy dog's back")
# => "e38ca1d920c4b8b8d3946b2c72f01680"
Rust
Cargo.toml
[dependencies]
rust-crypto = "0.2"
src/main.rs
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());
}
S-lang
Support for MD5 and SHA-1 are included in the standard "chksum" library:
require("chksum");
print(md5sum("The quick brown fox jumped over the lazy dog's back"));
- Output:
"e38ca1d920c4b8b8d3946b2c72f01680"
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]")
}
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;
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Sidef
var digest = frequire('Digest::MD5');
say digest.md5_hex("The quick brown fox jumped over the lazy dog's back");
The same in OO manner
var md5 = require('Digest::MD5').new;
md5.add("The quick brown fox jumped over the lazy dog's back");
say md5.hexdigest;
Slate
You must load the code in 'src/lib/md5.slate'.
'The quick brown fox jumped over the lazy dog\'s back' md5String. "==> 'e38ca1d920c4b8b8d3946b2c72f01680'"
Slope
(display (string->md5 "The quick brown fox jumped over the lazy dog's back"))
- Output:
e38ca1d920c4b8b8d3946b2c72f01680
Smalltalk
Using utility classes:
PackageLoader fileInPackage: 'Digest' !
(MD5 hexDigestOf: 'The quick brown fox jumped over the lazy dog''s back') displayNl.
(MD5Stream hashValueOf: 'The quick brown fox jumped over the lazy dog''s back') printCR.
SQL
SELECT MD5('The quick brown fox jumped over the lazy dog\'s back')
Suneido
Md5('The quick brown fox jumped over the lazy dog\'s back')
Tcl
package require md5
puts [md5::md5 -hex "The quick brown fox jumped over the lazy dog's back"]
# ==> E38CA1D920C4B8B8D3946B2C72F01680
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:
echo -n "The quick brown fox jumped over the lazy dog's back" | md5sum
Several BSD systems have md5:
echo -n "The quick brown fox jumped over the lazy dog's back" | md5
echo -n "The quick brown fox jumped over the lazy dog's back" |
openssl md5 | sed 's/.*= //'
Visual Basic .NET
Imports System.Security.Cryptography
Imports System.Text
Module MD5hash
Sub Main(args As String())
Console.WriteLine(GetMD5("Visual Basic .Net"))
End Sub
Private Function GetMD5(plainText As String) As String
Dim hash As String = ""
Using hashObject As MD5 = MD5.Create()
Dim ptBytes As Byte() = hashObject.ComputeHash(Encoding.UTF8.GetBytes(plainText))
Dim hashBuilder As New StringBuilder
For i As Integer = 0 To ptBytes.Length - 1
hashBuilder.Append(ptBytes(i).ToString("X2"))
Next
hash = hashBuilder.ToString
End Using
Return hash
End Function
End Module
- Output:
AF397EA30996B22759740AC66452D47A
V (Vlang)
import crypto.md5
fn main() {
for p in [
// 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])
}
}
fn validate(check string, s string) {
sum := md5.hexhash(s)
if sum != check {
println("MD5 fail")
println(" for string, $s")
println(" expected: $check")
println(" got: $sum")
} else {
println('MD5 succeeded $s')
}
}
- Output:
MD5 succeeded MD5 succeeded a MD5 succeeded abc MD5 succeeded message digest MD5 succeeded abcdefghijklmnopqrstuvwxyz MD5 succeeded ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 MD5 succeeded 12345678901234567890123456789012345678901234567890123456789012345678901234567890 MD5 succeeded The quick brown fox jumped over the lazy dog's back
Wren
This script uses a library implementation of MD5 (based on the implementation in the MD5/Implementation#Wren task) to process the Wikipedia examples.
import "./crypto" for Md5
import "./fmt" for Fmt
var strings = [
"The quick brown fox jumps over the lazy dog",
"The quick brown fox jumps over the lazy dog.",
""
]
for (s in strings) {
var digest = Md5.digest(s)
Fmt.print("$s <== '$0s'", digest, s)
}
- Output:
9e107d9d372bb6826bd81d3542a419d6 <== 'The quick brown fox jumps over the lazy dog' e4d909c290d0fb1ca068ffaddf22cbd0 <== 'The quick brown fox jumps over the lazy dog.' d41d8cd98f00b204e9800998ecf8427e <== ''
zkl
md5 is a built in utility
Utils.MD5.calc("message digest"); //-->"f96b697d7cb7938d525a2f31aaf161d0"
Utils.MD5.calc("abcdefghijklmnopqrstuvwxyz"); //-->"c3fcd3d76192e4007dfb496cca67e13b"
- Programming Tasks
- Checksums
- 8th
- AArch64 Assembly
- Ada
- ALGOL 68
- APL
- Arturo
- ARM Assembly
- AutoHotkey
- BaCon
- BASIC256
- BBC BASIC
- C
- OpenSSL
- C sharp
- C++
- Poco Crypto
- Caché ObjectScript
- Clojure
- COBOL
- Common Lisp
- Ironclad
- CFFI
- Crystal
- D
- Tango
- Delphi
- E
- EasyLang
- Emacs Lisp
- Erlang
- F Sharp
- Factor
- Forth
- Forth Foundation Library
- Fortran
- FreeBASIC
- Frink
- Futhark
- Go
- Groovy
- Haskell
- Cryptonite
- Haxe
- Icon
- Unicon
- Io
- J
- Java
- Jsish
- Julia
- Kotlin
- Lasso
- Liberty BASIC
- Lingo
- Crypto Xtra
- LiveCode
- Lua
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Min
- MOO
- Neko
- Nemerle
- NetRexx
- NewLISP
- Nim
- Nu
- Oberon-2
- Crypto
- Objeck
- Objective-C
- OCaml
- Octave
- Ol
- OpenEdge/Progress
- PARI/GP
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- PowerShell
- PureBasic
- Python
- R
- Racket
- Raku
- REBOL
- REXX
- Ring
- RLaB
- RPG
- Ruby
- Rust
- S-lang
- Scala
- Seed7
- Sidef
- Slate
- Slope
- Smalltalk
- SQL
- Suneido
- Tcl
- Tcllib
- UNIX Shell
- Visual Basic .NET
- V (Vlang)
- Wren
- Wren-crypto
- Wren-fmt
- Zkl
- GUISS/Omit