MD5/Implementation: Difference between revisions

m
→‎{{header|Raku}}: minor simplification
(Adding a groovy version (minor syntactic changes from the Java version))
m (→‎{{header|Raku}}: minor simplification)
 
(48 intermediate revisions by 20 users not shown)
Line 9:
** A translation of a correct implementation from another language
** A library routine in the same language; however, the source must be included here.
 
 
The solutions shown here will provide practical illustrations of bit manipulation, unsigned integers, working with little-endian data. Additionally, the task requires an attention to details such as boundary conditions since being out by even 1 bit will produce dramatically different results. Subtle implementation bugs can result in some hashes being correct while others are wrong. Not only is it critical to get the individual sub functions working correctly, even small errors in padding, endianness, or data layout will result in failure.
Line 26 ⟶ 27:
 
{{alertbox|#ffff70|'''<big>Warning</big>'''<br/>Rosetta Code is '''not''' a place you should rely on for examples of code in critical roles, including security.<br/>Also, note that MD5 has been ''broken'' and should not be used in applications requiring security. For these consider [[wp:SHA2|SHA2]] or the upcoming [[wp:SHA3|SHA3]].}}
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight 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,
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]
 
constants = (0.<64).map(i -> UInt32(UInt64(abs(sin(i + 1)) * 2.0 ^ 32) [&] FFFF'FFFF))
 
init_values = (UInt32(6745'2301), UInt32(EFCD'AB89), UInt32(98BA'DCFE), UInt32(1032'5476))
 
[((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
index_functions [+]= i -> i
index_functions [+]= i -> (5 * i + 1) % 16
index_functions [+]= i -> (3 * i + 5) % 16
index_functions [+]= i -> (7 * i) % 16
 
F md5(=message)
V orig_len_in_bits = UInt64(8) * message.len
message.append(8'0)
L message.len % 64 != 56
message.append(0)
message.extend(bytes_from_int(orig_len_in_bits))
 
V hash_pieces = init_values
 
L(chunk_ofst) (0 .< message.len).step(64)
V (a, b, c, d) = hash_pieces
V chunk = message[chunk_ofst .+ 64]
L(i) 64
V f = :functions[i I/ 16](b, c, d)
V g = :index_functions[i I/ 16](i)
V to_rotate = a + f + :constants[i] + UInt32(bytes' chunk[4 * g .+ 4])
V new_b = UInt32(b + rotl(to_rotate, :rotate_amounts[i]))
(a, b, c, d) = (d, new_b, b, c)
L(val) (a, b, c, d)
hash_pieces[L.index] += val
 
[Byte] r
L(x) hash_pieces
r.extend([x [&] F'F, (x >> 8) [&] F'F, (x >> 16) [&] F'F, (x >> 24) [&] F'F])
R r
 
F md5_to_hex(digest)
V s = ‘’
L(d) digest
s ‘’= hex(d).lowercase().zfill(2)
R s
 
V demo = [Bytes(‘’), Bytes(‘a’), Bytes(‘abc’), Bytes(‘message digest’), Bytes(‘abcdefghijklmnopqrstuvwxyz’),
Bytes(‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789’),
Bytes(‘12345678901234567890123456789012345678901234567890123456789012345678901234567890’)]
L(message) demo
print(md5_to_hex(md5(message))‘ <= "’message.decode(‘ascii’)‘"’)</syntaxhighlight>
 
{{out}}
<pre>
d41d8cd98f00b204e9800998ecf8427e <= ""
0cc175b9c0f1b6a831c399e269772661 <= "a"
900150983cd24fb0d6963f7d28e17f72 <= "abc"
f96b697d7cb7938d525a2f31aaf161d0 <= "message digest"
c3fcd3d76192e4007dfb496cca67e13b <= "abcdefghijklmnopqrstuvwxyz"
d174ab98d277d9f5a5611c2c9f419d9f <= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
57edf4a22be3c955ac49da2e2107b67a <= "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
</pre>
 
=={{header|Ada}}==
Line 31 ⟶ 106:
 
md5.ads:
<langsyntaxhighlight Adalang="ada">package MD5 is
 
type Int32 is mod 2 ** 32;
Line 41 ⟶ 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 265 ⟶ 340:
end To_String;
 
end MD5;</langsyntaxhighlight>
 
tester.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Strings.Unbounded;
with Ada.Text_IO;
with MD5;
Line 301 ⟶ 376:
Ada.Text_IO.Put_Line (To_String (Digests (I)) & " (correct value)");
end loop;
end Tester;</langsyntaxhighlight>
 
output:
Line 331 ⟶ 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 383 ⟶ 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 439 ⟶ 514:
WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE
WHILE n# < &80000000 : n# += 2^32 : ENDWHILE
= n#</langsyntaxhighlight>
 
=={{header|C}}==
Line 446 ⟶ 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 816 ⟶ 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 829 ⟶ 904:
}
password = s.ToString();
</syntaxhighlight>
</lang>
 
{{omit from|Clojure|Unavailable bit operations}}
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
# Array sum helper function.
sum = (array) ->
Line 900 ⟶ 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 908 ⟶ 983:
And tests:
 
<langsyntaxhighlight lang="coffeescript">
str2hex = do ->
hex = ['0', '1', '2', '3', '4', '5', '6', '7',
Line 925 ⟶ 1,000:
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
]
</syntaxhighlight>
</lang>
 
Output:
Line 942 ⟶ 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,064 ⟶ 1,139:
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")))
(assert (string= "57edf4a22be3c955ac49da2e2107b67a"
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"))))</langsyntaxhighlight>
 
=={{header|D}}==
Line 1,070 ⟶ 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,316 ⟶ 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,339 ⟶ 1,414:
As you see this asm is much faster than the D code compiled by dmd, but the D code compiled by ldc2 is a little faster still.
 
=={{header|F#Delphi}}==
{{libheader| System.SysUtils}}
Pure functional implementation (slower than library function) (Link to original blog [https://znprojects.blogspot.com/2017/04/md5-in-f-functionally.html]):
{{libheader| System.Classes}}
<lang F#>let fxyz x y z : uint32 = (x &&& y) ||| (~~~x &&& z)
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program MD5Implementation;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Classes;
 
type
TTestCase = record
hashCode: string;
_: string;
end;
 
var
testCases: array[0..6] of TTestCase = ((
hashCode: 'D41D8CD98F00B204E9800998ECF8427E';
_: ''
), (
hashCode: '0CC175B9C0F1B6A831C399E269772661';
_: 'a'
), (
hashCode: '900150983CD24FB0D6963F7D28E17F72';
_: 'abc'
), (
hashCode: 'F96B697D7CB7938D525A2F31AAF161D0';
_: 'message digest'
), (
hashCode: 'C3FCD3D76192E4007DFB496CCA67E13B';
_: 'abcdefghijklmnopqrstuvwxyz'
), (
hashCode: 'D174AB98D277D9F5A5611C2C9F419D9F';
_: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
), (
hashCode: '57EDF4A22BE3C955AC49DA2E2107B67A';
_: '12345678901234567890123456789' + '012345678901234567890123456789012345678901234567890'
));
shift: array of UInt32 = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21];
table: array[0..63] of UInt32;
 
procedure Init();
var
i: integer;
 
function fAbs(x: Extended): Extended;
begin
if x < 0 then
exit(-x);
exit(x);
end;
 
begin
for i := 0 to High(table) do
table[i] := Trunc((UInt64(1) shl 32) * fAbs(Sin(i + 1.0)));
end;
 
function Md5(s: string): TBytes;
const
BUFFER_SIZE = 16;
var
binary: TBytesStream;
buffer: Tarray<UInt32>;
messageLenBits: UInt64;
i, j, bufferIndex, count: integer;
byte_data: byte;
string_data: ansistring;
k, k1: Tarray<UInt32>;
f, rnd, sa: UInt32;
tmp: UInt64;
begin
k := [$67452301, $EFCDAB89, $98BADCFE, $10325476];
 
binary := TBytesStream.Create();
 
if not s.IsEmpty then
begin
string_data := Utf8ToAnsi(s);
binary.Write(Tbytes(string_data), length(string_data));
end;
 
byte_data := $80;
binary.Write(byte_data, 1);
 
messageLenBits := UInt64(s.Length * 8);
count := s.Length + 1;
 
while (count mod 64) <> 56 do
begin
byte_data := $00;
binary.Write(byte_data, 1);
inc(count);
end;
 
binary.Write(messageLenBits, sizeof(messageLenBits));
 
SetLength(buffer, BUFFER_SIZE);
SetLength(k1, length(k));
 
binary.Seek(0, soFromBeginning);
 
while binary.Read(buffer[0], BUFFER_SIZE * 4) > 0 do
begin
for i := 0 to 3 do
k1[i] := k[i];
 
for i := 0 to 63 do
begin
f := 0;
bufferIndex := i;
rnd := i shr 4;
case rnd of
0:
f := (k1[1] and k1[2]) or (not k1[1] and k1[3]);
1:
begin
f := (k1[1] and k1[3]) or (k1[2] and not k1[3]);
bufferIndex := (bufferIndex * 5 + 1) and $0F
end;
2:
begin
f := k1[1] xor k1[2] xor k1[3];
bufferIndex := (bufferIndex * 3 + 5) and $0F;
end;
3:
begin
f := k1[2] xor (k1[1] or not k1[3]);
bufferIndex := (bufferIndex * 7) and $0F;
end;
end;
 
sa := shift[(rnd shl 2) or (i and 3)];
 
k1[0] := k1[0] + f + buffer[bufferIndex] + table[i];
 
tmp := k1[0];
 
k1[0] := k1[3];
k1[3] := k1[2];
k1[2] := k1[1];
 
k1[1] := ((tmp shl sa) or (tmp shr (32 - sa))) + k1[1];
end;
 
for i := 0 to 3 do
k[i] := k[i] + k1[i];
end;
 
SetLength(result, BUFFER_SIZE);
 
binary.Clear;
for i := 0 to 3 do
binary.Write(k[i], 4);
 
binary.Seek(0, soBeginning);
 
binary.Read(Result, BUFFER_SIZE);
 
binary.Free;
end;
 
function BytesToString(b: TBytes): string;
var
v: byte;
begin
Result := '';
for v in b do
Result := Result + v.ToHexString(2);
end;
 
var
tc: TTestCase;
 
begin
Init;
 
for tc in testCases do
Writeln(Format('%s'#10'%s'#10, [tc.hashCode, BytesToString(md5(tc._))]));
Readln;
end.</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
#
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]):
<syntaxhighlight lang="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,437 ⟶ 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,589 ⟶ 1,957:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>
Line 1,621 ⟶ 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,701 ⟶ 2,069:
binary.Write(bytes.NewBuffer(r[:0]), binary.LittleEndian, []uint32{a, b, c, d})
return
}</langsyntaxhighlight>
Output:
<pre>
Line 1,725 ⟶ 2,093:
57edf4a22be3c955ac49da2e2107b67a
</pre>
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">
class MD5 {
 
Line 1,853 ⟶ 2,222:
}
 
</syntaxhighlight>
</lang>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Monad (replicateM)
 
import qualified Data.ByteString.Lazy as BL
Line 1,967 ⟶ 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,072 ⟶ 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,093 ⟶ 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,190 ⟶ 2,560:
)
 
md5_z_=: md5_pcrypt_</langsyntaxhighlight>
 
<langsyntaxhighlight lang="j"> md5''
d41d8cd98f00b204e9800998ecf8427e
md5'a'
Line 2,206 ⟶ 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,333 ⟶ 2,703:
}
}</langsyntaxhighlight>
 
<b>Output:</b>
Line 2,347 ⟶ 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,460 ⟶ 2,830:
}
}</langsyntaxhighlight>
 
<b>Output:</b>
Line 2,471 ⟶ 2,841:
0x57EDF4A22BE3C955AC49DA2E2107B67A <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
</pre>
 
 
=={{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,550 ⟶ 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,563 ⟶ 2,932:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
object MD5 {
Line 2,692 ⟶ 3,061:
println("0x${MD5.compute(s.toByteArray()).toHexString()} <== \"$s\"")
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,710 ⟶ 3,079:
 
=={{header|Lingo}}==
<langsyntaxhighlight Lingolang="lingo">----------------------------------------
-- Calculates MD5 hash of string or bytearray
-- @param {bytearray|string} input
Line 2,984 ⟶ 3,353:
ba.position = 1
return ba
end</langsyntaxhighlight>
 
<langsyntaxhighlight Lingolang="lingo">tests = []
tests.add("")
tests.add("a")
Line 2,997 ⟶ 3,366:
ba = md5(t)
put ba.toHexString(1, ba.length)
end repeat</langsyntaxhighlight>
 
{{out}}
Line 3,010 ⟶ 3,379:
</pre>
 
=={{header|MathematicaLua}}==
 
<lang Mathematica>md5[string_String] :=
With advent of 5.3, Lua can now calculate a string representation of an md5 hash.
 
<syntaxhighlight lang="lua">-- shift amounts
local 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
}
 
-- constants
local K = {
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,
}
 
local function leftRotate(x, c)
return (x << c) | (x >> (32-c))
end
 
local function getInt(byteArray, n)
return (byteArray[n+3]<<24) + (byteArray[n+2]<<16) + (byteArray[n+1]<<8) + byteArray[n]
end
 
--- converts 32bit integer n to a little endian hex representation
-- @tparam integer n
local function lE(n)
local s = ''
for i = 0, 3 do
s = ('%s%02x'):format(s, (n>>(i*8))&0xff)
end
return s
end
 
--- md5
-- @tparam string message
local function md5(message)
local a0, b0, c0, d0 = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
local bytes = {message:byte(1, -1)}
-- insert 1 bit (and the rest of the byte)
table.insert(bytes, 0x80)
 
-- pad with zeros until we have *just enough*
local p = #bytes%64
if p > 56 then
p = p - 64
end
for _ = p+1, 56 do
table.insert(bytes, 0)
end
 
-- insert the initial message length, in little-endian
local len = ((#message)<<3)&0xffffffffffffffff -- length in bits
for i = 0, 7 do
table.insert(bytes, (len>>(i*8))&0xff)
end
 
for i = 0, #bytes//64-1 do
local a, b, c, d = a0, b0, c0, d0
for j = 0, 63 do
local F, g
-- permutate
if j <= 15 then
F = (b & c) | (~b & d)
g = j
elseif j <= 31 then
F = (d & b) | (~d & c)
g = (5*j + 1) & 15
elseif j <= 47 then
F = b ~ c ~ d
g = (3*j + 5) & 15
else
F = c ~ (b | ~d)
g = (7*j) & 15
end
 
F = (F + a + K[j+1] + getInt(bytes, i*64+g*4+1))&0xffffffff
-- shuffle
a = d
d = c
c = b
b = (b + leftRotate(F, s[j+1]))&0xffffffff
end
-- update internal state
a0 = (a0 + a)&0xffffffff
b0 = (b0 + b)&0xffffffff
c0 = (c0 + c)&0xffffffff
d0 = (d0 + d)&0xffffffff
end
 
-- lua doesn't support any other byte strings. Could convert to a wacky string but this is more printable.
return lE(a0)..lE(b0)..lE(c0)..lE(d0)
end
 
local demo = {
[""] = "d41d8cd98f00b204e9800998ecf8427e",
["a"] = "0cc175b9c0f1b6a831c399e269772661",
["abc"] = "900150983cd24fb0d6963f7d28e17f72",
["message digest"] = "f96b697d7cb7938d525a2f31aaf161d0",
["abcdefghijklmnopqrstuvwxyz"] = "c3fcd3d76192e4007dfb496cca67e13b",
["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"] = "d174ab98d277d9f5a5611c2c9f419d9f",
["12345678901234567890123456789012345678901234567890123456789012345678901234567890"] = "57edf4a22be3c955ac49da2e2107b67a",
}
 
for k, v in pairs(demo) do
local m = md5(k)
print(("%s [%2s] <== \"%s\""):format(m, m==v and 'OK' or '', k))
end</syntaxhighlight>
 
Output:
<syntaxhighlight lang="lua">f96b697d7cb7938d525a2f31aaf161d0 [OK] <== "message digest"
d174ab98d277d9f5a5611c2c9f419d9f [OK] <== "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
c3fcd3d76192e4007dfb496cca67e13b [OK] <== "abcdefghijklmnopqrstuvwxyz"
d41d8cd98f00b204e9800998ecf8427e [OK] <== ""
900150983cd24fb0d6963f7d28e17f72 [OK] <== "abc"
57edf4a22be3c955ac49da2e2107b67a [OK] <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
0cc175b9c0f1b6a831c399e269772661 [OK] <== "a"
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="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,039 ⟶ 3,545:
FromDigits[
Flatten[Reverse@IntegerDigits[#, 256, 4] & /@ {h0, h1, h2, h3}],
256], 16, 32]]</syntaxhighlight>
</lang>
Example:
<langsyntaxhighlight Mathematicalang="mathematica">md5["12345678901234567890123456789012345678901234567890123456789012345678901234567890"]</langsyntaxhighlight>
Output:
<syntaxhighlight lang Mathematica="mathematica">0x57edf4a22be3c955ac49da2e2107b67a</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
Line 3,051 ⟶ 3,556:
=={{header|Modula-3}}==
 
<langsyntaxhighlight lang="modula3">INTERFACE MD5;
 
IMPORT Word;
Line 3,069 ⟶ 3,574:
PROCEDURE ToText(hash: Digest): TEXT;
 
END MD5.</langsyntaxhighlight>
<langsyntaxhighlight lang="modula3">MODULE MD5;
 
IMPORT Word, Text, Fmt;
Line 3,313 ⟶ 3,818:
 
BEGIN
END MD5.</langsyntaxhighlight>
Example usage:
<langsyntaxhighlight lang="modula3">MODULE Main;
 
IMPORT MD5, IO;
Line 3,325 ⟶ 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,332 ⟶ 3,837:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import sequtils
 
const
Line 3,342 ⟶ 3,847:
srcIndex = offset
 
for dstIndex in 0 .. < 16:
chunk[dstIndex] = 0
for ii in 0 .. < 4:
chunk[dstIndex] = chunk[dstIndex] shr 8
chunk[dstIndex] = chunk[dstIndex] or (msg[srcIndex].uint32 shl 24)
Line 3,398 ⟶ 3,903:
var sizePadding = newSeq[uint8](8)
var size = msg.len * 8
for ii in 0 .. < 4:
sizePadding[ii] = uint8(size and 0xff)
size = size shr 8
Line 3,452 ⟶ 3,957:
var tmp = acc
 
for ii in 0 .. < 4:
result[dstIdx] = uint8(tmp and 0xff)
tmp = tmp shr 8
Line 3,459 ⟶ 3,964:
# Only needed to convert from string to uint8 sequence
iterator items * (str : string) : uint8 =
for ii in 0 .. < len(str):
yield str[ii].uint8
 
Line 3,512 ⟶ 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,591 ⟶ 4,096:
index = 65
end
-- Only procesprocess completely filled buffer
do while index=65
A = a0
Line 3,648 ⟶ 4,153:
 
-- A convenience class to encapsulate operations on non OORexx-like
-- things such as little-endian 32-bit words
::class int32 public
 
Line 3,701 ⟶ 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 3,710 ⟶ 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 3,748 ⟶ 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 3,772 ⟶ 4,285:
}
 
sub rotate_left($$) {
($_[0] << $_[1]) | (( $_[0] >> (32 - $_[1]) ) & ((1 << $_[1]) - 1));
}
Line 3,915 ⟶ 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 3,929 ⟶ 4,442:
</pre>
 
=={{header|Perl 6Phix}}==
Non-optimised. Originally written by Davi Tassinari de Figueiredo.
{{works with|rakudo|2018.03}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>sub infix:<⊞>(uint32 $a, uint32 $b --> uint32) { ($a + $b) +& 0xffffffff }
<span style="color: #000080;font-style:italic;">-- demo\rosetta\md5.exw</span>
sub infix:«<<<»(uint32 $a, UInt $n --> uint32) { ($a +< $n) +& 0xffffffff +| ($a +> (32-$n)) }
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">data1</span><span style="color: #0000FF;">,</span><span style="color: #004080;">atom</span> <span style="color: #000000;">data2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">data2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">result</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">#100000000</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">data1</span><span style="color: #0000FF;">,</span><span style="color: #004080;">atom</span> <span style="color: #000000;">data2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">data2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">result</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">#100000000</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#100000000</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">word</span><span style="color: #0000FF;">,</span><span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- left rotate the bits of a 32-bit number by the specified number of bits</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))+</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">K</span> <span style="color: #0000FF;">=</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">#d76aa478</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#e8c7b756</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#242070db</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#c1bdceee</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#f57c0faf</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#4787c62a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#a8304613</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fd469501</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#698098d8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#8b44f7af</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#ffff5bb1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#895cd7be</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#6b901122</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fd987193</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#a679438e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#49b40821</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#f61e2562</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#c040b340</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#265e5a51</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#e9b6c7aa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#d62f105d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#02441453</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#d8a1e681</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#e7d3fbc8</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#21e1cde6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#c33707d6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#f4d50d87</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#455a14ed</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#a9e3e905</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fcefa3f8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#676f02d9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#8d2a4c8a</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#fffa3942</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#8771f681</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#6d9d6122</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fde5380c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#a4beea44</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#4bdecfa9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#f6bb4b60</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#bebfbc70</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#289b7ec6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#eaa127fa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#d4ef3085</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#04881d05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#d9d4d039</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#e6db99e5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#1fa27cf8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#c4ac5665</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#f4292244</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#432aff97</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#ab9423a7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fc93a039</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#655b59c3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#8f0ccc92</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#ffeff47d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#85845dd1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">#6fa87e4f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#fe2ce6e0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#a3014314</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#4e0811a1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#f7537e82</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#bd3af235</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#2ad7d2bb</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#eb86d391</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">m_block</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">c_words</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">#67452301</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#efcdab89</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#98badcfe</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#10325476</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">words</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">divide_in_words</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">message</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Divides the string into words (32-bit numbers)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">word</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">word</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">bytes_to_int</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">[</span><span style="color: #000000;">word</span><span style="color: #0000FF;">*</span><span style="color: #000000;">4</span><span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..</span><span style="color: #000000;">word</span><span style="color: #0000FF;">*</span><span style="color: #000000;">4</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">process_block</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">block</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Updates the words according to the contents of the block</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span>
<span style="color: #000000;">block</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">divide_in_words</span><span style="color: #0000FF;">(</span><span style="color: #000000;">block</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span>
<span style="color: #000080;font-style:italic;">-- Round 1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">16</span> <span style="color: #008080;">by</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span><span style="color: #000000;">d</span><span style="color: #0000FF;">))),</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span><span style="color: #000000;">c</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">12</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">),</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">17</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #000000;">a</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">22</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Round 2</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">=</span><span style="color: #000000;">17</span> <span style="color: #008080;">to</span> <span style="color: #000000;">32</span> <span style="color: #008080;">by</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)))),</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)))),</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)))),</span><span style="color: #000000;">14</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)))),</span><span style="color: #000000;">20</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Round 3</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">=</span><span style="color: #000000;">33</span> <span style="color: #008080;">to</span> <span style="color: #000000;">48</span> <span style="color: #008080;">by</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">))),</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">11</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">16</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">))),</span><span style="color: #000000;">23</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Round 4</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">=</span><span style="color: #000000;">49</span> <span style="color: #008080;">to</span> <span style="color: #000000;">64</span> <span style="color: #008080;">by</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span> <span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)))),</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)))),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)))),</span><span style="color: #000000;">15</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m_block</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">K</span><span style="color: #0000FF;">[</span><span style="color: #000000;">step</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">uxor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)))),</span><span style="color: #000000;">21</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Update the words</span>
<span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">pad_message</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">message</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Add bytes to the end of the message so it can be divided
-- in an exact number of 64-byte blocks.</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bytes_to_add</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">64</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">+</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">64</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bytes_to_add</span><span style="color: #0000FF;">=</span><span style="color: #000000;">64</span> <span style="color: #008080;">then</span> <span style="color: #000000;">bytes_to_add</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">message</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">message</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">#80</span>
<span style="color: #000000;">message</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bytes_to_add</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">message</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)&{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">message</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">md5</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">message</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Given a string, returns a 16-byte hash of it.</span>
<span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c_words</span> <span style="color: #000080;font-style:italic;">-- Initialize the H words</span>
<span style="color: #000000;">message</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pad_message</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- Add bytes to the message
-- Process each 64-byte block</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">block</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">64</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">process_block</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">[</span><span style="color: #000000;">block</span><span style="color: #0000FF;">..</span><span style="color: #000000;">block</span><span style="color: #0000FF;">+</span><span style="color: #000000;">63</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Convert hash into bytes</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])&</span> <span style="color: #000080;font-style:italic;">-- Return the hash</span>
<span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])&</span>
<span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])&</span>
<span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">include_file</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
constant FGHI = { ($^a +& $^b) +| (+^$a +& $^c) },
<span style="color: #004080;">string</span> <span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n"</span>
{ ($^a +& $^c) +| ($^b +& +^$c) },
{ $^a +^ $^b +^ $^c },
<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;">""</span><span style="color: #0000FF;">))</span>
{ $^b +^ ($^a +| +^$^c) };
<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;">"a"</span><span style="color: #0000FF;">))</span>
<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;">"abc"</span><span style="color: #0000FF;">))</span>
constant _S = flat (7, 12, 17, 22) xx 4,
<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;">"message digest"</span><span style="color: #0000FF;">))</span>
(5, 9, 14, 20) xx 4,
<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;">"abcdefghijklmnopqrstuvwxyz"</span><span style="color: #0000FF;">))</span>
(4, 11, 16, 23) xx 4,
<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;">"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"</span><span style="color: #0000FF;">))</span>
(6, 10, 15, 21) xx 4;
<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>
constant T = (floor(abs(sin($_ + 1)) * 2**32) for ^64);
<!--</syntaxhighlight>-->
constant k = flat ( $_ for ^16),
((5*$_ + 1) % 16 for ^16),
((3*$_ + 5) % 16 for ^16),
((7*$_ ) % 16 for ^16);
sub little-endian($w, $n, *@v) {
my \step1 = $w X* ^$n;
my \step2 = @v X+> step1;
step2 X% 2**$w;
}
sub md5-pad(Blob $msg)
{
my $bits = 8 * $msg.elems;
my @padded = flat $msg.list, 0x80, 0x00 xx -($bits div 8 + 1 + 8) % 64;
flat @padded.map({ :256[$^d,$^c,$^b,$^a] }), little-endian(32, 2, $bits);
}
sub md5-block(@H, @X)
{
my uint32 ($A, $B, $C, $D) = @H;
($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);
}
 
sub md5(Blob $msg --> Blob)
{
my uint32 @M = md5-pad($msg);
my uint32 @H = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
md5-block(@H, @M[$_ .. $_+15]) for 0, 16 ...^ +@M;
Blob.new: little-endian(8, 4, @H);
}
use Test;
plan 7;
for 'd41d8cd98f00b204e9800998ecf8427e', '',
'0cc175b9c0f1b6a831c399e269772661', 'a',
'900150983cd24fb0d6963f7d28e17f72', 'abc',
'f96b697d7cb7938d525a2f31aaf161d0', 'message digest',
'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}}
<pre>1..7
ok 1 - d41d8cd98f00b204e9800998ecf8427e is MD5 digest of ''
ok 2 - 0cc175b9c0f1b6a831c399e269772661 is MD5 digest of 'a'
ok 3 - 900150983cd24fb0d6963f7d28e17f72 is MD5 digest of 'abc'
ok 4 - f96b697d7cb7938d525a2f31aaf161d0 is MD5 digest of 'message digest'
ok 5 - c3fcd3d76192e4007dfb496cca67e13b is MD5 digest of 'abcdefghijklmnopqrstuvwxyz'
ok 6 - d174ab98d277d9f5a5611c2c9f419d9f is MD5 digest of 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
ok 7 - 57edf4a22be3c955ac49da2e2107b67a is MD5 digest of '12345678901234567890123456789012345678901234567890123456789012345678901234567890'</pre>
 
=={{header|Phix}}==
Non-optimised. Originally written by Davi Tassinari de Figueiredo. Included in the distribution as demo\rosetta\md5.exw
<lang Phix>function uxor(atom data1,atom data2)
atom result = xor_bits(data1,data2)
if result<0 then result += #100000000 end if
return result
end function
 
function uor(atom data1,atom data2)
atom result = or_bits(data1,data2)
if result<0 then result += #100000000 end if
return result
end function
 
function r32(atom a)
return remainder(a,#100000000)
end function
 
function rol(atom word,integer bits)
-- left rotate the bits of a 32-bit number by the specified number of bits
return r32(word*power(2,bits))+floor(word/power(2,32-bits))
end function
 
constant K =
{#d76aa478, #e8c7b756, #242070db, #c1bdceee, #f57c0faf, #4787c62a, #a8304613, #fd469501,
#698098d8, #8b44f7af, #ffff5bb1, #895cd7be, #6b901122, #fd987193, #a679438e, #49b40821,
#f61e2562, #c040b340, #265e5a51, #e9b6c7aa, #d62f105d, #02441453, #d8a1e681, #e7d3fbc8,
#21e1cde6, #c33707d6, #f4d50d87, #455a14ed, #a9e3e905, #fcefa3f8, #676f02d9, #8d2a4c8a,
#fffa3942, #8771f681, #6d9d6122, #fde5380c, #a4beea44, #4bdecfa9, #f6bb4b60, #bebfbc70,
#289b7ec6, #eaa127fa, #d4ef3085, #04881d05, #d9d4d039, #e6db99e5, #1fa27cf8, #c4ac5665,
#f4292244, #432aff97, #ab9423a7, #fc93a039, #655b59c3, #8f0ccc92, #ffeff47d, #85845dd1,
#6fa87e4f, #fe2ce6e0, #a3014314, #4e0811a1, #f7537e82, #bd3af235, #2ad7d2bb, #eb86d391}
 
constant m_block = {1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
2, 7,12, 1, 6,11,16, 5,10,15, 4, 9,14, 3, 8,13,
6, 9,12,15, 2, 5, 8,11,14, 1, 4, 7,10,13,16, 3,
1, 8,15, 6,13, 4,11, 2, 9,16, 7,14, 5,12, 3,10}
 
constant c_words = {#67452301,#efcdab89,#98badcfe,#10325476}
 
sequence words
 
function divide_in_words(sequence message)
-- Divides the string into words (32-bit numbers)
sequence res
res = repeat(0,length(message)/4)
for word=1 to length(message)/4 do
res[word] = bytes_to_int(message[word*4-3..word*4])
end for
return res
end function
 
procedure process_block(sequence block)
-- Updates the words according to the contents of the block
atom a,b,c,d
 
block = divide_in_words(block)
 
a = words[1]
b = words[2]
c = words[3]
d = words[4]
 
-- Round 1
for step=1 to 16 by 4 do
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uor(and_bits(b,c),and_bits(not_bits(b),d))), 7))
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uor(and_bits(a,b),and_bits(not_bits(a),c))),12))
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uor(and_bits(d,a),and_bits(not_bits(d),b))),17))
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uor(and_bits(c,d),and_bits(not_bits(c),a))),22))
end for
 
-- Round 2
for step=17 to 32 by 4 do
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uor(and_bits(b,d),and_bits(c,not_bits(d)))), 5))
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uor(and_bits(a,c),and_bits(b,not_bits(c)))), 9))
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uor(and_bits(d,b),and_bits(a,not_bits(b)))),14))
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uor(and_bits(c,a),and_bits(d,not_bits(a)))),20))
end for
 
-- Round 3
for step=33 to 48 by 4 do
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uxor(b,xor_bits(c,d))), 4))
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uxor(a,xor_bits(b,c))),11))
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uxor(d,xor_bits(a,b))),16))
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uxor(c,xor_bits(d,a))),23))
end for
 
-- Round 4
for step=49 to 64 by 4 do
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uxor(c,or_bits(b,not_bits(d)))), 6))
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uxor(b,or_bits(a,not_bits(c)))),10))
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uxor(a,or_bits(d,not_bits(b)))),15))
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uxor(d,or_bits(c,not_bits(a)))),21))
end for
 
-- Update the words
words[1] = r32(words[1]+a)
words[2] = r32(words[2]+b)
words[3] = r32(words[3]+c)
words[4] = r32(words[4]+d)
end procedure
 
function pad_message(sequence message)
-- Add bytes to the end of the message so it can be divided
-- in an exact number of 64-byte blocks.
integer bytes_to_add
bytes_to_add = 64-remainder(length(message)+9,64)
if bytes_to_add=64 then bytes_to_add = 0 end if
 
message = message&#80&repeat(0,bytes_to_add)&
int_to_bytes(length(message)*8)&{0,0,0,0}
 
return message
end function
 
 
function md5(sequence message)
-- Given a string, returns a 16-byte hash of it.
 
words = c_words -- Initialize the H words
 
message = pad_message(message) -- Add bytes to the message
 
-- Process each 64-byte block
for block=1 to length(message) by 64 do
process_block(message[block..block+63])
end for
 
-- Convert hash into bytes
return int_to_bytes(words[1])& -- Return the hash
int_to_bytes(words[2])&
int_to_bytes(words[3])&
int_to_bytes(words[4])
 
end function
 
constant fmt = "0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n"
 
printf(1,fmt,md5(""))
printf(1,fmt,md5("a"))
printf(1,fmt,md5("abc"))
printf(1,fmt,md5("message digest"))
printf(1,fmt,md5("abcdefghijklmnopqrstuvwxyz"))
printf(1,fmt,md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))
printf(1,fmt,md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890"))</lang>
{{out}}
<pre>
Line 4,159 ⟶ 4,606:
0x57edf4a22be3c955ac49da2e2107b67a
</pre>
 
 
=={{header|PicoLisp}}==
Line 4,165 ⟶ 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,259 ⟶ 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,282 ⟶ 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,343 ⟶ 4,789:
for message in demo:
print(md5_to_hex(md5(message)),' <= "',message.decode('ascii'),'"', sep='')
</syntaxhighlight>
</lang>
 
Implementation notes:
Line 4,354 ⟶ 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|2024-02}}
<syntaxhighlight lang="raku" line>proto md5($msg) returns Blob is export {*}
multi md5(Str $msg) { md5 $msg.encode }
multi md5(Blob $msg) {
my buf8 $buf .= new;
$buf.write-uint32: $buf.elems, $_, LittleEndian for
reduce -> Blob $blob, blob32 $X {
blob32.new: $blob Z+
reduce -> $b, $i {
blob32.new:
$b[3],
$b[1] +
-> uint32 \x, \n { (x +< n) +| (x +> (32-n)) }(
($b[0] + (BEGIN Array.new:
{ ($^x +& $^y) +| (+^$x +& $^z) },
{ ($^x +& $^z) +| ($^y +& +^$z) },
{ $^x +^ $^y +^ $^z },
{ $^y +^ ($^x +| +^$^z) }
)[$i div 16](|$b[1..3]) +
(BEGIN blob32.new: map &floor ∘ * * 2**32 ∘ &abs ∘ &sin ∘ * + 1, ^64)[$i] +
$X[(BEGIN Blob.new: 16 X[R%] flat ($++, 5*$++ + 1, 3*$++ + 5, 7*$++) Xxx 16)[$i]]
) mod 2**32,
(BEGIN flat < 7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21 >.rotor(4) Xxx 4)[$i]
),
$b[1],
$b[2]
}, $blob, |^64;
},
(BEGIN blob32.new: 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476),
|map { blob32.new: @$_ },
{
$^b.push(blob8.new(@$_).read-uint32(0)) for (@$msg, 0x80, 0x00 xx (-($msg.elems + 1 + 8) % 64))
.flat.rotor(4);
$b.write-uint64: $b.elems, 8*$msg.elems, LittleEndian;
$b;
}(buf32.new)
.rotor(16);
$buf;
}
 
CHECK {
use Test;
 
for 'd41d8cd98f00b204e9800998ecf8427e', '',
'0cc175b9c0f1b6a831c399e269772661', 'a',
'900150983cd24fb0d6963f7d28e17f72', 'abc',
'f96b697d7cb7938d525a2f31aaf161d0', 'message digest',
'c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz',
'd174ab98d277d9f5a5611c2c9f419d9f', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'57edf4a22be3c955ac49da2e2107b67a', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
-> $expected, $msg {
my $digest = md5($msg).list».fmt('%02x').join;
is($digest, $expected, "$digest is MD5 digest of '$msg'");
}
done-testing;
}</syntaxhighlight>
 
{{out}}
<pre>1..7
ok 1 - d41d8cd98f00b204e9800998ecf8427e is MD5 digest of ''
ok 2 - 0cc175b9c0f1b6a831c399e269772661 is MD5 digest of 'a'
ok 3 - 900150983cd24fb0d6963f7d28e17f72 is MD5 digest of 'abc'
ok 4 - f96b697d7cb7938d525a2f31aaf161d0 is MD5 digest of 'message digest'
ok 5 - c3fcd3d76192e4007dfb496cca67e13b is MD5 digest of 'abcdefghijklmnopqrstuvwxyz'
ok 6 - d174ab98d277d9f5a5611c2c9f419d9f is MD5 digest of 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
ok 7 - 57edf4a22be3c955ac49da2e2107b67a is MD5 digest of '12345678901234567890123456789012345678901234567890123456789012345678901234567890'</pre>
 
=={{header|REXX}}==
This REXX program uses the test suite that is from the IETF RFC (1321) contained in the
&nbsp; ''MD5 Message─Digest Algorithm'', &nbsp; April 1992.
<br>April 1992.
<lang rexx>/*REXX program tests the MD5 procedure (below) as per a test suite from IETF RFC (1321).*/
<syntaxhighlight 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,384 ⟶ 4,900:
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
#= 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, ··· */
$=! || "80"x || copies('0'x,plus%8-1)reverse(right(d2c(8*#), 4, '0'x)) || '00000000'x
/* [↑] ··· and a little of that.*/
do j=0 for length($) % 64 /*process the message (lots of steps).*/
a_= a; b_= b; c_= c; d_=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 = .p1( a, b, c, d, 0, 7, 3614090360) /*■■■■ 1 ■■■■*/
Line 4,480 ⟶ 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,508 ⟶ 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 4,750 ⟶ 5,266:
1700485571 2399980690 4293915773 2240044497
1873313359 4264355552 2734768916 1309151649
4149444226 3174756917 718787259 3951481745</langsyntaxhighlight>
 
Sample output:
Line 4,758 ⟶ 5,274:
DSPLY InputLen=26
DSPLY MD5: C3FCD3D76192E4007DFB496CCA67E13B</pre>
 
 
=={{header|Rust}}==
Line 4,768 ⟶ 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.
 
<syntaxhighlight lang="rust">
<lang C>
#![allow(non_snake_case)] // RFC 1321 uses many capitalized variables
use std::mem;
Line 5,007 ⟶ 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,064 ⟶ 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,085 ⟶ 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,105 ⟶ 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,128 ⟶ 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,153 ⟶ 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,163 ⟶ 5,782:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">class MD5(String msg) {
 
method init {
Line 5,248 ⟶ 5,867:
 
for i in (range(0, M.end, 16)) {
md5_block(H, M.ftslice(i, i+15).first(16))
}
 
Line 5,272 ⟶ 5,891:
say "\tHowever, that is incorrect (expected: #{md5})"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,290 ⟶ 5,909:
Original source: [//github.com/krzyzanowskim/CryptoSwift CryptoSwift]
 
<langsyntaxhighlight lang="swift">
import Foundation
public class MD5 {
Line 5,417 ⟶ 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,502 ⟶ 6,121:
println(toHexString(md5(Array(string.utf8))))
println()
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,529 ⟶ 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 5,773 ⟶ 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 5,785 ⟶ 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.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var k = [
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
]
 
var 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, 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
]
 
var leftRotate = Fn.new { |x, c| (x << c) | (x >> (32 - c)) }
 
var toBytes = Fn.new { |val|
var bytes = List.filled(4, 0)
bytes[0] = val & 255
bytes[1] = (val >> 8) & 255
bytes[2] = (val >> 16) & 255
bytes[3] = (val >> 24) & 255
return bytes
}
 
var toInt = Fn.new { |bytes| bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24 }
 
var md5 = Fn.new { |initMsg|
var h0 = 0x67452301
var h1 = 0xefcdab89
var h2 = 0x98badcfe
var h3 = 0x10325476
var initBytes = initMsg.bytes
var initLen = initBytes.count
var newLen = initLen + 1
while (newLen % 64 != 56) newLen = newLen + 1
var msg = List.filled(newLen + 8, 0)
for (i in 0...initLen) msg[i] = initBytes[i]
msg[initLen] = 0x80 // remaining bytes already 0
var lenBits = toBytes.call(initLen * 8)
for (i in newLen...newLen+4) msg[i] = lenBits[i-newLen]
var extraBits = toBytes.call(initLen >> 29)
for (i in newLen+4...newLen+8) msg[i] = extraBits[i-newLen-4]
var offset = 0
var w = List.filled(16, 0)
while (offset < newLen) {
for (i in 0...16) w[i] = toInt.call(msg[offset+i*4...offset + i*4 + 4])
var a = h0
var b = h1
var c = h2
var d = h3
var f
var g
for (i in 0...64) {
if (i < 16) {
f = (b & c) | ((~b) & d)
g = i
} else if (i < 32) {
f = (d & b) | ((~d) & c)
g = (5*i + 1) % 16
} else if (i < 48) {
f = b ^ c ^ d
g = (3*i + 5) % 16
} else {
f = c ^ (b | (~d))
g = (7*i) % 16
}
var temp = d
d = c
c = b
b = b + leftRotate.call((a + f + k[i] + w[g]), r[i])
a = temp
}
h0 = h0 + a
h1 = h1 + b
h2 = h2 + c
h3 = h3 + d
offset = offset + 64
}
var digest = List.filled(16, 0)
var dBytes = toBytes.call(h0)
for (i in 0...4) digest[i] = dBytes[i]
dBytes = toBytes.call(h1)
for (i in 0...4) digest[i+4] = dBytes[i]
dBytes = toBytes.call(h2)
for (i in 0...4) digest[i+8] = dBytes[i]
dBytes = toBytes.call(h3)
for (i in 0...4) digest[i+12] = dBytes[i]
return digest
}
 
var strings = [
"",
"a",
"abc",
"message digest",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
]
 
for (s in strings) {
var digest = md5.call(s)
Fmt.print("0x$s <== '$0s'", Fmt.v("xz", 2, digest, 0, "", ""), s)
}</syntaxhighlight>
 
{{out}}
<pre>
0xd41d8cd98f00b204e9800998ecf8427e <== ''
0x0cc175b9c0f1b6a831c399e269772661 <== 'a'
0x900150983cd24fb0d6963f7d28e17f72 <== 'abc'
0xf96b697d7cb7938d525a2f31aaf161d0 <== 'message digest'
0xc3fcd3d76192e4007dfb496cca67e13b <== 'abcdefghijklmnopqrstuvwxyz'
0xd174ab98d277d9f5a5611c2c9f419d9f <== 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
0x57edf4a22be3c955ac49da2e2107b67a <== '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
</pre>
 
=={{header|x86 Assembly}}==
Line 5,792 ⟶ 6,545:
Uses DOS interrupts for display.
 
<langsyntaxhighlight lang="asm">section .text
org 0x100
mov di, md5_for_display
Line 6,058 ⟶ 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