MD5/Implementation: Difference between revisions

m
→‎{{header|Raku}}: minor simplification
m (→‎{{header|Raku}}: minor simplification)
 
(25 intermediate revisions by 12 users not shown)
Line 31:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">-V
rotate_amounts = [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,
Line 42:
 
[((UInt32, UInt32, UInt32) -> UInt32)] functions
functions [+]= (b, c, d) -> (b [&] c) [|] ((-)~b [&] d)
functions [+]= (b, c, d) -> (d [&] b) [|] ((-)~d [&] c)
functions [+]= (b, c, d) -> b (+) c (+) d
functions [+]= (b, c, d) -> c (+) (b [|] (-)~d)
 
[(Int -> Int)] index_functions
Line 89:
Bytes(‘12345678901234567890123456789012345678901234567890123456789012345678901234567890’)]
L(message) demo
print(md5_to_hex(md5(message))‘ <= "’message.decode(‘ascii’)‘"’)</langsyntaxhighlight>
 
{{out}}
Line 106:
 
md5.ads:
<langsyntaxhighlight Adalang="ada">package MD5 is
 
type Int32 is mod 2 ** 32;
Line 116:
function To_String (Item : MD5_Hash) return MD5_String;
 
end MD5;</langsyntaxhighlight>
 
md5.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Unchecked_Conversion;
 
package body MD5 is
Line 340:
end To_String;
 
end MD5;</langsyntaxhighlight>
 
tester.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Strings.Unbounded;
with Ada.Text_IO;
with MD5;
Line 376:
Ada.Text_IO.Put_Line (To_String (Digests (I)) & " (correct value)");
end loop;
end Tester;</langsyntaxhighlight>
 
output:
Line 406:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> PRINT FN_MD5("")
PRINT FN_MD5("a")
PRINT FN_MD5("abc")
Line 458:
REM Break chunk into sixteen 32-bit little-endian words:
FOR i% = 0 TO 15
w%(i%) = !(!^PTR(message$) + 64*chunk% + 4*i%)
NEXT i%
Line 514:
WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE
WHILE n# < &80000000 : n# += 2^32 : ENDWHILE
= n#</langsyntaxhighlight>
 
=={{header|C}}==
Line 521:
=={{header|C sharp}}==
Handwritten implementation ([http://farazmahmood.wordpress.com/projects/md5-implementation-in-c/]):
<langsyntaxhighlight lang="csharp">
/// Represent digest with ABCD
sealed public class Digest
Line 891:
}
 
</syntaxhighlight>
</lang>
 
Standard library-based implementation:
<langsyntaxhighlight lang="csharp">
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(password);
Line 904:
}
password = s.ToString();
</syntaxhighlight>
</lang>
 
{{omit from|Clojure|Unavailable bit operations}}
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
# Array sum helper function.
sum = (array) ->
Line 975:
(String.fromCharCode x >>> 8 * y & 255 for y in [0..3]).join ''
).join ''
</syntaxhighlight>
</lang>
 
This implementation is more focused towards brevity rather than speed. Use a javascript MD5 implementation if speed is desired. Fork this code [https://gist.github.com/Higgs1/08ec61fbb250c1c92151 on github].
Line 983:
And tests:
 
<langsyntaxhighlight lang="coffeescript">
str2hex = do ->
hex = ['0', '1', '2', '3', '4', '5', '6', '7',
Line 1,000:
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
]
</syntaxhighlight>
</lang>
 
Output:
Line 1,017:
This code requires the [https://github.com/cl-babel/babel BABEL] package for converting a string to an octet buffer.
 
<langsyntaxhighlight lang="lisp">(defpackage #:md5
(:use #:cl))
 
Line 1,139:
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")))
(assert (string= "57edf4a22be3c955ac49da2e2107b67a"
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"))))</langsyntaxhighlight>
 
=={{header|D}}==
Line 1,145:
 
This code generates x86 assembly code by compile time functions, then mix-in the assembly code. It only works on x86 machine.
<langsyntaxhighlight lang="d">import std.bitmanip, core.stdc.string, std.conv, std.math, std.array,
std.string;
 
Line 1,391:
writefln("zmd5 : %8.2f M/sec ( %8.2f secs)",
megaBytes / time2, time2);
}</langsyntaxhighlight>
{{out|Output (dmd compiler)}}
<pre>md5 digest("") = D41D8CD98F00B204E9800998ECF8427E
Line 1,418:
{{libheader| System.Classes}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program MD5Implementation;
 
Line 1,597:
Writeln(Format('%s'#10'%s'#10, [tc.hashCode, BytesToString(md5(tc._))]));
Readln;
end.</langsyntaxhighlight>
 
=={{header|F#EasyLang}}==
<syntaxhighlight lang="text">
len md5k[] 64
proc md5init . .
for i = 1 to 64
md5k[i] = floor (0x100000000 * abs sin (i * 180 / pi))
.
.
md5init
#
proc md5 inp$ . s$ .
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
.
s$ = ""
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
.
.
.
.
repeat
s$ = input
until error = 1
md5 s$ h$
print h$
.
input_data
a
abc
message digest
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
12345678901234567890123456789012345678901234567890123456789012345678901234567890
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
Pure functional implementation (slower than library function) (Link to original blog [https://zakaluka.github.io/2017/04/23/md5-in-f-functionally.html]):
<langsyntaxhighlight Flang="f#">let fxyz x y z : uint32 = (x &&& y) ||| (~~~x &&& z)
let gxyz x y z : uint32 = (z &&& x) ||| (~~~z &&& y)
let hxyz x y z : uint32 = x ^^^ y ^^^ z
Line 1,697 ⟶ 1,805:
|> (fun x -> System.BitConverter.GetBytes d |> Array.append x))
|> Array.map (sprintf "%02X")
|> Array.reduce (+)</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 19-10-2016
' MD5 from the Wikipedia page "MD5"
' compile with: fbc -s console
Line 1,849 ⟶ 1,957:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>
Line 1,881 ⟶ 1,989:
=={{header|Go}}==
A limitation from RFC 1321 is that the function md5 takes a string which is a number of whole bytes. Messages of arbitrary bit length are not supported.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,961 ⟶ 2,069:
binary.Write(bytes.NewBuffer(r[:0]), binary.LittleEndian, []uint32{a, b, c, d})
return
}</langsyntaxhighlight>
Output:
<pre>
Line 1,987 ⟶ 2,095:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">
class MD5 {
 
Line 2,114 ⟶ 2,222:
}
 
</syntaxhighlight>
</lang>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Monad (replicateM)
 
import qualified Data.ByteString.Lazy as BL
Line 2,229 ⟶ 2,337:
w = datA ! (idxA ! i)
a' = b + (a + f b c d + w + sinA ! i) `rotateL` rotA ! i
in MD5 d a' b c</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
The following program is based on part on the Wikipedia pseudo-code and in part on the reference implementation in RFC 1321. The implementation uses large integers. The solution works in both Icon and Unicon. One limitation of this implementation is that will not handle arbitrary (bit) length messages - all are byte aligned. Another small challenge was that Icon/Unicon bit manipulation functions work on signed integers (and large integers), as a result there are no native rotation and negation functions.
<langsyntaxhighlight Iconlang="icon">procedure main() # validate against the RFC test strings and more
testMD5("The quick brown fox jumps over the lazy dog", 16r9e107d9d372bb6826bd81d3542a419d6)
testMD5("The quick brown fox jumps over the lazy dog.", 16re4d909c290d0fb1ca068ffaddf22cbd0)
Line 2,334 ⟶ 2,442:
end
 
link unsigned # string to unsigned integer</langsyntaxhighlight>
 
The {{libheader|Icon Programming Library}} provides [http://www.cs.arizona.edu/icon/library/src/procs/unsigned.icn unsigned] and [http://www.cs.arizona.edu/icon/library/src/procs/hexcvt.icn hexcvt]
Line 2,355 ⟶ 2,463:
Note: the following code was extracted from http://www.jsoftware.com/wsvn/addons/trunk/convert/misc/md5.ijs
 
<langsyntaxhighlight lang="j">NB. convert/misc/md5
NB. RSA Data Security, Inc. MD5 Message-Digest Algorithm
NB. version: 1.0.2
Line 2,452 ⟶ 2,560:
)
 
md5_z_=: md5_pcrypt_</langsyntaxhighlight>
 
<langsyntaxhighlight lang="j"> md5''
d41d8cd98f00b204e9800998ecf8427e
md5'a'
Line 2,468 ⟶ 2,576:
md5'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
57edf4a22be3c955ac49da2e2107b67a
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
{{works with|Java|1.5+}}
Based on RFC-1321.
<langsyntaxhighlight lang="java">class MD5
{
 
Line 2,595 ⟶ 2,703:
}
}</langsyntaxhighlight>
 
<b>Output:</b>
Line 2,609 ⟶ 2,717:
{{works with|Java|1.5+}}
Using <code>ByteBuffer</code>s
<langsyntaxhighlight lang="java">import java.nio.ByteBuffer;
import java.nio.ByteOrder;
 
Line 2,722 ⟶ 2,830:
}
}</langsyntaxhighlight>
 
<b>Output:</b>
Line 2,735 ⟶ 2,843:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia"># a rather literal translation of the pseudocode at https://en.wikipedia.org/wiki/MD5
 
const s = UInt32[7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 2,811 ⟶ 2,919:
println("MD5 of $(pair[2]) is $(md5(pair[2])), which checks with $(string(pair[1], base=16)).")
end
</langsyntaxhighlight>{{out}}
<pre>
MD5 of is d41d8cd98f00b204e9800998ecf8427e, which checks with d41d8cd98f00b204e9800998ecf8427e.
Line 2,824 ⟶ 2,932:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
object MD5 {
Line 2,953 ⟶ 3,061:
println("0x${MD5.compute(s.toByteArray()).toHexString()} <== \"$s\"")
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,971 ⟶ 3,079:
 
=={{header|Lingo}}==
<langsyntaxhighlight Lingolang="lingo">----------------------------------------
-- Calculates MD5 hash of string or bytearray
-- @param {bytearray|string} input
Line 3,245 ⟶ 3,353:
ba.position = 1
return ba
end</langsyntaxhighlight>
 
<langsyntaxhighlight Lingolang="lingo">tests = []
tests.add("")
tests.add("a")
Line 3,258 ⟶ 3,366:
ba = md5(t)
put ba.toHexString(1, ba.length)
end repeat</langsyntaxhighlight>
 
{{out}}
Line 3,275 ⟶ 3,383:
With advent of 5.3, Lua can now calculate a string representation of an md5 hash.
 
<langsyntaxhighlight lang="lua">-- shift amounts
local s = {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 3,396 ⟶ 3,504:
local m = md5(k)
print(("%s [%2s] <== \"%s\""):format(m, m==v and 'OK' or '', k))
end</langsyntaxhighlight>
 
Output:
<langsyntaxhighlight lang="lua">f96b697d7cb7938d525a2f31aaf161d0 [OK] <== "message digest"
d174ab98d277d9f5a5611c2c9f419d9f [OK] <== "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
c3fcd3d76192e4007dfb496cca67e13b [OK] <== "abcdefghijklmnopqrstuvwxyz"
Line 3,406 ⟶ 3,514:
57edf4a22be3c955ac49da2e2107b67a [OK] <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
0cc175b9c0f1b6a831c399e269772661 [OK] <== "a"
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">md5[string_String] :=
Module[{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, 9, 14, 20, 5, 9, 14, 20, 4,
Line 3,437 ⟶ 3,545:
FromDigits[
Flatten[Reverse@IntegerDigits[#, 256, 4] & /@ {h0, h1, h2, h3}],
256], 16, 32]]</langsyntaxhighlight>
Example:
<langsyntaxhighlight Mathematicalang="mathematica">md5["12345678901234567890123456789012345678901234567890123456789012345678901234567890"]</langsyntaxhighlight>
Output:
<syntaxhighlight lang Mathematica="mathematica">0x57edf4a22be3c955ac49da2e2107b67a</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
Line 3,448 ⟶ 3,556:
=={{header|Modula-3}}==
 
<langsyntaxhighlight lang="modula3">INTERFACE MD5;
 
IMPORT Word;
Line 3,466 ⟶ 3,574:
PROCEDURE ToText(hash: Digest): TEXT;
 
END MD5.</langsyntaxhighlight>
<langsyntaxhighlight lang="modula3">MODULE MD5;
 
IMPORT Word, Text, Fmt;
Line 3,710 ⟶ 3,818:
 
BEGIN
END MD5.</langsyntaxhighlight>
Example usage:
<langsyntaxhighlight lang="modula3">MODULE Main;
 
IMPORT MD5, IO;
Line 3,722 ⟶ 3,830:
MD5.Update(md5ctx, "The quick brown fox jumped over the lazy dog's back");
IO.Put(MD5.ToText(MD5.Final(md5ctx)) & "\n");
END Main.</langsyntaxhighlight>
Output:
<pre>
Line 3,729 ⟶ 3,837:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import sequtils
 
const
Line 3,909 ⟶ 4,017:
0x0D, 0x5B, 0x09, 0x84, 0x09, 0x64, 0x44, 0x57 ])
 
main()</langsyntaxhighlight>
 
=={{header|ooRexx}}==
{{works with|ooRexx|4.2.0 (and later)}}
<syntaxhighlight lang="oorexx">
<lang ooRexx>
#!/usr/bin/env rexx
 
/* Expected results:
Line 3,988 ⟶ 4,096:
index = 65
end
-- Only procesprocess completely filled buffer
do while index=65
A = a0
Line 4,045 ⟶ 4,153:
 
-- A convenience class to encapsulate operations on non OORexx-like
-- things such as little-endian 32-bit words
::class int32 public
 
Line 4,098 ⟶ 4,206:
bstring = bstring~substr(bits+1)~left(bstring~length,'0')
return .int32~new(bstring~b2x~x2d)
 
-- For those who like to code the shift operation in a traditional way
::method '<<'
forward to (self) message("bitleft")
 
::method bitright -- OORexx shift (>>) implementation
Line 4,107 ⟶ 4,219:
bstring = bstring~left(bstring~length-bits)~right(bstring~length,fill)
return .int32~new(bstring~b2x~x2d)
 
-- For those who like to code the shift operation in a traditional way
::method '>>'
forward to (self) message("bitright")
 
::method bitnot -- OORexx not implementation
Line 4,145 ⟶ 4,261:
-- Simplify function names for the necessary 'RxMath' functions
::routine sin EXTERNAL "LIBRARY rxmath RxCalcSin"
</syntaxhighlight>
</lang>
 
=={{header|Perl}}==
{{works with|Perl|5.10.1 (and later)}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use integer;
Line 4,169 ⟶ 4,285:
}
 
sub rotate_left($$) {
($_[0] << $_[1]) | (( $_[0] >> (32 - $_[1]) ) & ((1 << $_[1]) - 1));
}
Line 4,312 ⟶ 4,428:
II,$d,$a,$b,$c,$_[15],10,0xbd3af235,/* 62 */
II,$c,$d,$a,$b,$_[6],15,0x2ad7d2bb,/* 63 */
II,$b,$c,$d,$a,$_[13],21,0xeb86d391,/* 64 */</langsyntaxhighlight>
 
{{out}}
Line 4,328 ⟶ 4,444:
=={{header|Phix}}==
Non-optimised. Originally written by Davi Tassinari de Figueiredo.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\md5.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,479 ⟶ 4,595:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">md5</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"12345678901234567890123456789012345678901234567890123456789012345678901234567890"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 4,495 ⟶ 4,611:
care had to be taken with modulo 32-bit arithmetics, as PicoLisp supports only
numbers of unspecified size.
<langsyntaxhighlight PicoLisplang="picolisp">(scl 12)
(load "@lib/math.l") # For 'sin'
 
Line 4,589 ⟶ 4,705:
(do 4 # Convert to little endian hex string
(link (pad 2 (hex (& N 255))))
(setq N (>> 8 N)) ) ) ) ) ) )</langsyntaxhighlight>
Output:
<pre>: (md5 "")
Line 4,612 ⟶ 4,728:
Note that the following code focuses on brevity and elegance instead of performance, since Python isn't very good at number crunching anyway. If performance is important, the best solution is to use the built-in '''md5''' module, written in C.
 
<langsyntaxhighlight lang="python">import math
 
rotate_amounts = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 4,673 ⟶ 4,789:
for message in demo:
print(md5_to_hex(md5(message)),' <= "',message.decode('ascii'),'"', sep='')
</syntaxhighlight>
</lang>
 
Implementation notes:
Line 4,684 ⟶ 4,800:
=={{header|Racket}}==
For an implementation of md5 in Racket see: github.com/racket/racket/blob/master/racket/collects/file/md5.rkt
<langsyntaxhighlight lang="racket">
#lang racket
(require file/md5)
(md5 #"Rosetta Code")
</syntaxhighlight>
</lang>
Output:
<langsyntaxhighlight lang="racket">
#"cca1bf66b09554e10f837838c3d3efb1"
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2018.032024-02}}
<syntaxhighlight lang="raku" line>proto md5($msg) returns Blob is export {*}
<lang perl6>sub infix:<⊞>(uint32 $a, uint32 $b --> uint32) { ($a + $b) +& 0xffffffff }
multi md5(Str $msg) { md5 $msg.encode }
sub infix:«<<<»(uint32 $a, UInt $n --> uint32) { ($a +< $n) +& 0xffffffff +| ($a +> (32-$n)) }
multi md5(Blob $msg) {
my buf8 $buf .= new;
constant FGHI = { ($^a +& $^b) +| (+^$a +& $^c) },
$buf.write-uint32: $buf.elems, $_, LittleEndian for
{ ($^a +& $^c) +| ($^b +& +^$c) },
reduce -> Blob $blob, blob32 $X {
{ $^a +^ $^b +^ $^c },
blob32.new: $blob Z+
{ $^b +^ ($^a +| +^$^c) };
reduce -> $b, $i {
blob32.new:
constant _S = flat (7, 12, 17, 22) xx 4,
(5, 9, 14, 20) xx 4$b[3],
$b[1] (4, 11, 16, 23) xx 4,+
-> uint32 \x, \n { (6,x 10,+< 15, 21n) xx+| 4;(x +> (32-n)) }(
($b[0] + (BEGIN Array.new:
constant T = (floor(abs(sin { ($_^x +& 1)$^y) *+| 2**32)(+^$x for+& $^64z); },
{ ($^x +& $^z) +| ($^y +& +^$z) },
constant k = flat ( $_ { $^x +^ $^y for+^ $^16)z },
{ $^y +^ ((5*$_^x +| 1) % 16 for +^16$^z), }
)[$i div (16](|$b[1..3*$_]) + 5) % 16 for ^16),
(BEGIN blob32.new: map &floor ∘ ((7*$_ * 2**32 )&abs % 16&sin for∘ * + 1, ^1664);[$i] +
$X[(BEGIN Blob.new: 16 X[R%] flat ($++, 5*$++ + 1, 3*$++ + 5, 7*$++) Xxx 16)[$i]]
) mod 2**32,
sub little-endian($w, $n, *@v) {
(BEGIN flat < 7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21 >.rotor(4) Xxx 4)[$i]
my \step1 = $w X* ^$n;
my \step2 = @v X+> step1; ),
step2 X% 2** $w;b[1],
$b[2]
}
}, $blob, |^64;
},
sub md5-pad(Blob $msg)
(BEGIN blob32.new: 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476),
{
|map { blob32.new: @$_ },
my $bits = 8 * $msg.elems;
{
my @padded = flat $msg.list, 0x80, 0x00 xx -($bits div 8 + 1 + 8) % 64;
$^b.push(blob8.new(@$_).read-uint32(0)) for (@$msg, 0x80, 0x00 xx (-($msg.elems + 1 + 8) % 64))
flat @padded.map({ :256[$^d,$^c,$^b,$^a] }), little-endian(32, 2, $bits);
.flat.rotor(4);
}
$b.write-uint64: $b.elems, 8*$msg.elems, LittleEndian;
$b;
sub md5-block(@H, @X)
}(buf32.new)
{
.rotor(16);
my uint32 ($A, $B, $C, $D) = @H;
$buf;
($A, $B, $C, $D) = ($D, $B ⊞ (($A ⊞ FGHI[$_ div 16]($B, $C, $D) ⊞ T[$_] ⊞ @X[k[$_]]) <<< _S[$_]), $B, $C) for ^64;
@H «⊞=» ($A, $B, $C, $D);
}
 
CHECK {
sub md5(Blob $msg --> Blob)
use Test;
{
 
my uint32 @M = md5-pad($msg);
for 'd41d8cd98f00b204e9800998ecf8427e', '',
my uint32 @H = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
'0cc175b9c0f1b6a831c399e269772661', 'a',
md5-block(@H, @M[$_ .. $_+15]) for 0, 16 ...^ +@M;
'900150983cd24fb0d6963f7d28e17f72', 'abc',
Blob.new: little-endian(8, 4, @H);
'f96b697d7cb7938d525a2f31aaf161d0', 'message digest',
}
'c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz',
'd174ab98d277d9f5a5611c2c9f419d9f', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
use Test;
'57edf4a22be3c955ac49da2e2107b67a', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
plan 7;
-> $expected, $msg {
my $digest = md5($msg).list».fmt('%02x').join;
for 'd41d8cd98f00b204e9800998ecf8427e', '',
is($digest, $expected, "$digest is MD5 digest of '$msg'");
'0cc175b9c0f1b6a831c399e269772661', 'a',
}
'900150983cd24fb0d6963f7d28e17f72', 'abc',
done-testing;
'f96b697d7cb7938d525a2f31aaf161d0', 'message digest',
}</syntaxhighlight>
'c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz',
'd174ab98d277d9f5a5611c2c9f419d9f', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'57edf4a22be3c955ac49da2e2107b67a', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
-> $expected, $msg {
my $digest = md5($msg.encode('ascii')).list».fmt('%02x').join;
is($digest, $expected, "$digest is MD5 digest of '$msg'");
}</lang>
 
{{out}}
Line 4,774 ⟶ 4,883:
&nbsp; ''MD5 Message─Digest Algorithm'', &nbsp;
<br>April 1992.
<langsyntaxhighlight lang="rexx">/*REXX program tests the MD5 procedure (below) as per a test suite from IETF RFC (1321).*/
@.1 = /*─────MD5 test suite [from above doc].*/
@.2 = 'a'
Line 4,887 ⟶ 4,996:
return .a(.Lr(right(d2c(_+c2d(w) + c2d(.h(x,y,z)) + c2d(!.n)),4,'0'x),m),x)
.p4: 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)</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 4,915 ⟶ 5,024:
Based on my Java implementation. Uses free-form RPG and a CTDATA section to hold lookup tables. Converts input from EBCDIC to ASCII before hashing.
 
<langsyntaxhighlight RPGlang="rpg">**FREE
Ctl-opt MAIN(Main);
Ctl-opt DFTACTGRP(*NO) ACTGRP(*NEW);
Line 5,157 ⟶ 5,266:
1700485571 2399980690 4293915773 2240044497
1873313359 4264355552 2734768916 1309151649
4149444226 3174756917 718787259 3951481745</langsyntaxhighlight>
 
Sample output:
Line 5,174 ⟶ 5,283:
As with others implementations, this will not allow bit-lengths non-divisible by 8; this ability can be added in about 8 lines of code but no examples appear to be available for verification of correctness, and so it was elided.
 
<langsyntaxhighlight lang="rust">
#![allow(non_snake_case)] // RFC 1321 uses many capitalized variables
use std::mem;
Line 5,413 ⟶ 5,522:
assert!(md5_utf8("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == "57edf4a22be3c955ac49da2e2107b67a");
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
<lang Scala>object MD5 extends App {
 
{{trans|Java}}
def hash(s: String) = {
def b = s.getBytes("UTF-8")
 
def m = java.security.MessageDigest.getInstance("MD5").digest(b)
 
Based on RFC-1321.
BigInt(1, m).toString(16).reverse.padTo(32, "0").reverse.mkString
 
 
<syntaxhighlight lang="Scala">
import java.lang.Math
 
object MD5 {
private val INIT_A = 0x67452301
private val INIT_B = 0xEFCDAB89
private val INIT_C = 0x98BADCFE
private val INIT_D = 0x10325476
 
private val SHIFT_AMTS = Array(
7, 12, 17, 22,
5, 9, 14, 20,
4, 11, 16, 23,
6, 10, 15, 21
)
 
private val TABLE_T = Array.tabulate(64)(i => (Math.abs(Math.sin(i + 1)) * (1L << 32)).toLong.toInt)
 
def computeMD5(message: Array[Byte]): Array[Byte] = {
val messageLenBytes = message.length
val numBlocks = ((messageLenBytes + 8) >>> 6) + 1
val totalLen = numBlocks << 6
val paddingBytes = Array.fill[Byte](totalLen - messageLenBytes)(0)
paddingBytes(0) = 0x80.toByte
 
var messageLenBits = messageLenBytes.toLong << 3
for (i <- 0 until 8) {
paddingBytes(paddingBytes.length - 8 + i) = messageLenBits.toByte
messageLenBits >>>= 8
}
 
var a = INIT_A
var b = INIT_B
var c = INIT_C
var d = INIT_D
val buffer = new Array[Int](16)
 
for (i <- 0 until numBlocks) {
var index = i << 6
for (j <- 0 until 64) {
buffer(j >>> 2) = (((if (index < messageLenBytes) message(index) else paddingBytes(index - messageLenBytes)) << 24) | (buffer(j >>> 2) >>> 8)).toInt
index += 1
}
val originalA = a
val originalB = b
val originalC = c
val originalD = d
 
for (j <- 0 until 64) {
val div16 = j >>> 4
val bufferIndex = j match {
case j if j < 16 => j
case j if j < 32 => (j * 5 + 1) & 0x0F
case j if j < 48 => (j * 3 + 5) & 0x0F
case j => (j * 7) & 0x0F
}
 
val f = div16 match {
case 0 => (b & c) | (~b & d)
case 1 => (b & d) | (c & ~d)
case 2 => b ^ c ^ d
case 3 => c ^ (b | ~d)
}
 
val temp = b + Integer.rotateLeft(a + f + buffer(bufferIndex) + TABLE_T(j), SHIFT_AMTS((div16 << 2) | (j & 3)))
a = d
d = c
c = b
b = temp
}
 
a += originalA
b += originalB
c += originalC
d += originalD
}
 
val md5 = new Array[Byte](16)
var count = 0
for (i <- 0 until 4) {
var n = i match {
case 0 => a
case 1 => b
case 2 => c
case 3 => d
}
for (j <- 0 until 4) {
md5(count) = n.toByte
n >>>= 8
count += 1
}
}
md5
}
 
def toHexString(b: Array[Byte]): String = b.map(byte => f"$byte%02X").mkString
assert("d41d8cd98f00b204e9800998ecf8427e" == hash(""))
assert("0000045c5e2b3911eb937d9d8c574f09" == hash("iwrupvqb346386"))
assert("0cc175b9c0f1b6a831c399e269772661" == hash("a"))
assert("900150983cd24fb0d6963f7d28e17f72" == hash("abc"))
assert("f96b697d7cb7938d525a2f31aaf161d0" == hash("message digest"))
assert("c3fcd3d76192e4007dfb496cca67e13b" == hash("abcdefghijklmnopqrstuvwxyz"))
assert("d174ab98d277d9f5a5611c2c9f419d9f" == hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))
assert("57edf4a22be3c955ac49da2e2107b67a" == hash("12345678901234567890123456789012345678901234567890123456789012345678901234567890"))
 
def main(args: Array[String]): Unit = {
}</lang>
val testStrings = Array("", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890")
testStrings.foreach { s =>
println(s"0x${toHexString(computeMD5(s.getBytes))} <== \"$s\"")
}
}
}
</syntaxhighlight>
{{out}}
<pre>
0xD41D8CD98F00B204E9800998ECF8427E <== ""
0x0CC175B9C0F1B6A831C399E269772661 <== "a"
0x900150983CD24FB0D6963F7D28E17F72 <== "abc"
0xF96B697D7CB7938D525A2F31AAF161D0 <== "message digest"
0xC3FCD3D76192E4007DFB496CCA67E13B <== "abcdefghijklmnopqrstuvwxyz"
0xD174AB98D277D9F5A5611C2C9F419D9F <== "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
0x57EDF4A22BE3C955AC49DA2E2107B67A <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
 
</pre>
 
=={{header|Seed7}}==
The example below contains the implementation of the function [http://seed7.sourceforge.net/libraries/msgdigest.htm#md5%28in_var_string%29 md5] from the library [http://seed7.sourceforge.net/libraries/msgdigest.htm msgdigest.s7i].
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bytedata.s7i";
include "bin32.s7i";
Line 5,470 ⟶ 5,682:
const array integer: k is createMd5Table;
var integer: length is 0;
var integer: chunkIndexwordIndex is 01;
var integer: index is 0;
var array bin32: m is 16 times bin32.value;
Line 5,491 ⟶ 5,703:
message &:= "\0;" mult 63 - (length + 8) mod 64;
# Append length of message (before pre-processing), in bits, as 64-bit little-endian integer.
message &:= int64AsEightBytesLebytes(8 * length, UNSIGNED, LE, 8);
 
# Process the message in successive 512-bit chunks:
forwhile chunkIndexwordIndex range 1 to<= length(message) step 64 do
# Break chunk into sixteen 32-bit little-endian words.
for index range 1 to 16 do
m[index] := bin32(bytes2Int(message[chunkIndexwordIndex + 4 * pred(index) lenfixLen 4], UNSIGNED, LE));
wordIndex +:= 4;
end for;
 
Line 5,511 ⟶ 5,724:
elsif index <= 32 then
f := c >< (d & (b >< c));
g := succ((5 * index - 4) mod 16 + 1);
elsif index <= 48 then
f := b >< c >< d;
g := succ((3 * index + 2) mod 16 + 1);
else
f := c >< (b | (bin32(16#ffffffff) >< d));
g := succ((7 * pred(index)) mod 16 + 1);
end if;
 
Line 5,534 ⟶ 5,747:
c0 +:= ord(c);
d0 +:= ord(d);
end forwhile;
 
# Produce the final hash value:
digest := int32AsFourBytesLebytes(a0 mod 16#100000000, UNSIGNED, LE, 4) &
int32AsFourBytesLebytes(b0 mod 16#100000000, UNSIGNED, LE, 4) &
int32AsFourBytesLebytes(c0 mod 16#100000000, UNSIGNED, LE, 4) &
int32AsFourBytesLebytes(d0 mod 16#100000000, UNSIGNED, LE, 4);
end func;
 
Line 5,559 ⟶ 5,772:
writeln("There is an error in the md5 function");
end if;
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/msgdigest.htm#md5]
Line 5,570 ⟶ 5,783:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">class MD5(String msg) {
 
method init {
Line 5,654 ⟶ 5,867:
 
for i in (range(0, M.end, 16)) {
md5_block(H, M.ftslice(i, i+15).first(16))
}
 
Line 5,678 ⟶ 5,891:
say "\tHowever, that is incorrect (expected: #{md5})"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,696 ⟶ 5,909:
Original source: [//github.com/krzyzanowskim/CryptoSwift CryptoSwift]
 
<langsyntaxhighlight lang="swift">
import Foundation
public class MD5 {
Line 5,823 ⟶ 6,036:
}
}
</syntaxhighlight>
</lang>
 
From-scratch implementation based on the solutions on this page without needing any external libraries:
<langsyntaxhighlight lang="swift">import Foundation
 
let shift : [UInt32] = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21]
Line 5,908 ⟶ 6,121:
println(toHexString(md5(Array(string.utf8))))
println()
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,935 ⟶ 6,148:
=={{header|Tcl}}==
<small>This code is extracted from the <code>md5</code> package in {{libheader|tcllib}}, and is originally due to Don Libes's transcription of the code in the MD5 specification. ''It should not be deployed in production normally; the <code>md5</code> package should be used in preference as it is usually built to be faster.</small>
<langsyntaxhighlight lang="tcl"># We just define the body of md5::md5 here; later we regsub to inline a few
# function calls for speed
variable ::md5::md5body {
Line 6,179 ⟶ 6,392:
format %0.2x%0.2x%0.2x%0.2x [byte0 $i] [byte1 $i] [byte2 $i] [byte3 $i]
}
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">foreach {hash <- string} {
0xd41d8cd98f00b204e9800998ecf8427e ==> ""
0x0cc175b9c0f1b6a831c399e269772661 ==> "a"
Line 6,191 ⟶ 6,404:
} {
puts "“$string” -> [md5::md5 $string] (officially: $hash)"
}</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
This is a translation of the C code [https://github.com/pod32g/MD5/blob/master/md5.c here]. In the interests of brevity, the original comments have been omitted.
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var k = [
Line 6,314 ⟶ 6,527:
var digest = md5.call(s)
Fmt.print("0x$s <== '$0s'", Fmt.v("xz", 2, digest, 0, "", ""), s)
}</langsyntaxhighlight>
 
{{out}}
Line 6,332 ⟶ 6,545:
Uses DOS interrupts for display.
 
<langsyntaxhighlight lang="asm">section .text
org 0x100
mov di, md5_for_display
Line 6,598 ⟶ 6,811:
test_input_6_len equ $ - test_input_6
test_input_7 db '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
test_input_7_len equ $ - test_input_7</langsyntaxhighlight>
 
'''Output:'''
1,934

edits