MD5/Implementation: Difference between revisions
m
→{{header|Raku}}: minor simplification
Alextretyak (talk | contribs) |
m (→{{header|Raku}}: minor simplification) |
||
(25 intermediate revisions by 12 users not shown) | |||
Line 31:
{{trans|Python}}
<
rotate_amounts = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
Line 42:
[((UInt32, UInt32, UInt32) -> UInt32)] functions
functions [+]= (b, c, d) -> (b [&] c) [|] (
functions [+]= (b, c, d) -> (d [&] b) [|] (
functions [+]= (b, c, d) -> b (+) c (+) d
functions [+]= (b, c, d) -> c (+) (b [|]
[(Int -> Int)] index_functions
Line 89:
Bytes(‘12345678901234567890123456789012345678901234567890123456789012345678901234567890’)]
L(message) demo
print(md5_to_hex(md5(message))‘ <= "’message.decode(‘ascii’)‘"’)</
{{out}}
Line 106:
md5.ads:
<
type Int32 is mod 2 ** 32;
Line 116:
function To_String (Item : MD5_Hash) return MD5_String;
end MD5;</
md5.adb:
<
package body MD5 is
Line 340:
end To_String;
end MD5;</
tester.adb:
<
with Ada.Text_IO;
with MD5;
Line 376:
Ada.Text_IO.Put_Line (To_String (Digests (I)) & " (correct value)");
end loop;
end Tester;</
output:
Line 406:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
PRINT FN_MD5("a")
PRINT FN_MD5("abc")
Line 458:
REM Break chunk into sixteen 32-bit little-endian words:
FOR i% = 0 TO 15
w%(i%) = !(
NEXT i%
Line 514:
WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE
WHILE n# < &80000000 : n# += 2^32 : ENDWHILE
= n#</
=={{header|C}}==
Line 521:
=={{header|C sharp}}==
Handwritten implementation ([http://farazmahmood.wordpress.com/projects/md5-implementation-in-c/]):
<
/// Represent digest with ABCD
sealed public class Digest
Line 891:
}
</syntaxhighlight>
Standard library-based implementation:
<
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(password);
Line 904:
}
password = s.ToString();
</syntaxhighlight>
{{omit from|Clojure|Unavailable bit operations}}
=={{header|CoffeeScript}}==
<
# Array sum helper function.
sum = (array) ->
Line 975:
(String.fromCharCode x >>> 8 * y & 255 for y in [0..3]).join ''
).join ''
</syntaxhighlight>
This implementation is more focused towards brevity rather than speed. Use a javascript MD5 implementation if speed is desired. Fork this code [https://gist.github.com/Higgs1/08ec61fbb250c1c92151 on github].
Line 983:
And tests:
<
str2hex = do ->
hex = ['0', '1', '2', '3', '4', '5', '6', '7',
Line 1,000:
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
]
</syntaxhighlight>
Output:
Line 1,017:
This code requires the [https://github.com/cl-babel/babel BABEL] package for converting a string to an octet buffer.
<
(:use #:cl))
Line 1,139:
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")))
(assert (string= "57edf4a22be3c955ac49da2e2107b67a"
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"))))</
=={{header|D}}==
Line 1,145:
This code generates x86 assembly code by compile time functions, then mix-in the assembly code. It only works on x86 machine.
<
std.string;
Line 1,391:
writefln("zmd5 : %8.2f M/sec ( %8.2f secs)",
megaBytes / time2, time2);
}</
{{out|Output (dmd compiler)}}
<pre>md5 digest("") = D41D8CD98F00B204E9800998ECF8427E
Line 1,418:
{{libheader| System.Classes}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program MD5Implementation;
Line 1,597:
Writeln(Format('%s'#10'%s'#10, [tc.hashCode, BytesToString(md5(tc._))]));
Readln;
end.</
=={{header|
<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]):
<
let gxyz x y z : uint32 = (z &&& x) ||| (~~~z &&& y)
let hxyz x y z : uint32 = x ^^^ y ^^^ z
Line 1,697 ⟶ 1,805:
|> (fun x -> System.BitConverter.GetBytes d |> Array.append x))
|> Array.map (sprintf "%02X")
|> Array.reduce (+)</
=={{header|FreeBASIC}}==
<
' MD5 from the Wikipedia page "MD5"
' compile with: fbc -s console
Line 1,849 ⟶ 1,957:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre>
Line 1,881 ⟶ 1,989:
=={{header|Go}}==
A limitation from RFC 1321 is that the function md5 takes a string which is a number of whole bytes. Messages of arbitrary bit length are not supported.
<
import (
Line 1,961 ⟶ 2,069:
binary.Write(bytes.NewBuffer(r[:0]), binary.LittleEndian, []uint32{a, b, c, d})
return
}</
Output:
<pre>
Line 1,987 ⟶ 2,095:
=={{header|Groovy}}==
<
class MD5 {
Line 2,114 ⟶ 2,222:
}
</syntaxhighlight>
=={{header|Haskell}}==
<
import qualified Data.ByteString.Lazy as BL
Line 2,229 ⟶ 2,337:
w = datA ! (idxA ! i)
a' = b + (a + f b c d + w + sinA ! i) `rotateL` rotA ! i
in MD5 d a' b c</
=={{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.
<
testMD5("The quick brown fox jumps over the lazy dog", 16r9e107d9d372bb6826bd81d3542a419d6)
testMD5("The quick brown fox jumps over the lazy dog.", 16re4d909c290d0fb1ca068ffaddf22cbd0)
Line 2,334 ⟶ 2,442:
end
link unsigned # string to unsigned integer</
The {{libheader|Icon Programming Library}} provides [http://www.cs.arizona.edu/icon/library/src/procs/unsigned.icn unsigned] and [http://www.cs.arizona.edu/icon/library/src/procs/hexcvt.icn hexcvt]
Line 2,355 ⟶ 2,463:
Note: the following code was extracted from http://www.jsoftware.com/wsvn/addons/trunk/convert/misc/md5.ijs
<
NB. RSA Data Security, Inc. MD5 Message-Digest Algorithm
NB. version: 1.0.2
Line 2,452 ⟶ 2,560:
)
md5_z_=: md5_pcrypt_</
<
d41d8cd98f00b204e9800998ecf8427e
md5'a'
Line 2,468 ⟶ 2,576:
md5'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
57edf4a22be3c955ac49da2e2107b67a
</syntaxhighlight>
=={{header|Java}}==
{{works with|Java|1.5+}}
Based on RFC-1321.
<
{
Line 2,595 ⟶ 2,703:
}
}</
<b>Output:</b>
Line 2,609 ⟶ 2,717:
{{works with|Java|1.5+}}
Using <code>ByteBuffer</code>s
<
import java.nio.ByteOrder;
Line 2,722 ⟶ 2,830:
}
}</
<b>Output:</b>
Line 2,735 ⟶ 2,843:
=={{header|Julia}}==
<
const s = UInt32[7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 2,811 ⟶ 2,919:
println("MD5 of $(pair[2]) is $(md5(pair[2])), which checks with $(string(pair[1], base=16)).")
end
</
<pre>
MD5 of is d41d8cd98f00b204e9800998ecf8427e, which checks with d41d8cd98f00b204e9800998ecf8427e.
Line 2,824 ⟶ 2,932:
=={{header|Kotlin}}==
{{trans|Java}}
<
object MD5 {
Line 2,953 ⟶ 3,061:
println("0x${MD5.compute(s.toByteArray()).toHexString()} <== \"$s\"")
}
}</
{{out}}
Line 2,971 ⟶ 3,079:
=={{header|Lingo}}==
<
-- Calculates MD5 hash of string or bytearray
-- @param {bytearray|string} input
Line 3,245 ⟶ 3,353:
ba.position = 1
return ba
end</
<
tests.add("")
tests.add("a")
Line 3,258 ⟶ 3,366:
ba = md5(t)
put ba.toHexString(1, ba.length)
end repeat</
{{out}}
Line 3,275 ⟶ 3,383:
With advent of 5.3, Lua can now calculate a string representation of an md5 hash.
<
local s = {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 3,396 ⟶ 3,504:
local m = md5(k)
print(("%s [%2s] <== \"%s\""):format(m, m==v and 'OK' or '', k))
end</
Output:
<
d174ab98d277d9f5a5611c2c9f419d9f [OK] <== "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
c3fcd3d76192e4007dfb496cca67e13b [OK] <== "abcdefghijklmnopqrstuvwxyz"
Line 3,406 ⟶ 3,514:
57edf4a22be3c955ac49da2e2107b67a [OK] <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
0cc175b9c0f1b6a831c399e269772661 [OK] <== "a"
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
Module[{r = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17,
22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4,
Line 3,437 ⟶ 3,545:
FromDigits[
Flatten[Reverse@IntegerDigits[#, 256, 4] & /@ {h0, h1, h2, h3}],
256], 16, 32]]</
Example:
<
Output:
<syntaxhighlight lang
=={{header|MATLAB}} / {{header|Octave}}==
Line 3,448 ⟶ 3,556:
=={{header|Modula-3}}==
<
IMPORT Word;
Line 3,466 ⟶ 3,574:
PROCEDURE ToText(hash: Digest): TEXT;
END MD5.</
<
IMPORT Word, Text, Fmt;
Line 3,710 ⟶ 3,818:
BEGIN
END MD5.</
Example usage:
<
IMPORT MD5, IO;
Line 3,722 ⟶ 3,830:
MD5.Update(md5ctx, "The quick brown fox jumped over the lazy dog's back");
IO.Put(MD5.ToText(MD5.Final(md5ctx)) & "\n");
END Main.</
Output:
<pre>
Line 3,729 ⟶ 3,837:
=={{header|Nim}}==
<
const
Line 3,909 ⟶ 4,017:
0x0D, 0x5B, 0x09, 0x84, 0x09, 0x64, 0x44, 0x57 ])
main()</
=={{header|ooRexx}}==
{{works with|ooRexx|4.2.0 (and later)}}
<syntaxhighlight lang="oorexx">
#!/usr/bin/env rexx
/* Expected results:
Line 3,988 ⟶ 4,096:
index = 65
end
-- Only
do while index=65
A = a0
Line 4,045 ⟶ 4,153:
-- A convenience class to encapsulate operations on non OORexx-like
-- things such as little-endian 32-bit words
::class int32 public
Line 4,098 ⟶ 4,206:
bstring = bstring~substr(bits+1)~left(bstring~length,'0')
return .int32~new(bstring~b2x~x2d)
-- For those who like to code the shift operation in a traditional way
::method '<<'
forward to (self) message("bitleft")
::method bitright -- OORexx shift (>>) implementation
Line 4,107 ⟶ 4,219:
bstring = bstring~left(bstring~length-bits)~right(bstring~length,fill)
return .int32~new(bstring~b2x~x2d)
-- For those who like to code the shift operation in a traditional way
::method '>>'
forward to (self) message("bitright")
::method bitnot -- OORexx not implementation
Line 4,145 ⟶ 4,261:
-- Simplify function names for the necessary 'RxMath' functions
::routine sin EXTERNAL "LIBRARY rxmath RxCalcSin"
</syntaxhighlight>
=={{header|Perl}}==
{{works with|Perl|5.10.1 (and later)}}
<
use warnings;
use integer;
Line 4,169 ⟶ 4,285:
}
sub rotate_left
($_[0] << $_[1]) | (( $_[0] >> (32 - $_[1]) ) & ((1 << $_[1]) - 1));
}
Line 4,312 ⟶ 4,428:
II,$d,$a,$b,$c,$_[15],10,0xbd3af235,/* 62 */
II,$c,$d,$a,$b,$_[6],15,0x2ad7d2bb,/* 63 */
II,$b,$c,$d,$a,$_[13],21,0xeb86d391,/* 64 */</
{{out}}
Line 4,328 ⟶ 4,444:
=={{header|Phix}}==
Non-optimised. Originally written by Davi Tassinari de Figueiredo.
<!--<
<span style="color: #000080;font-style:italic;">-- demo\rosetta\md5.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,479 ⟶ 4,595:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">md5</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"12345678901234567890123456789012345678901234567890123456789012345678901234567890"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</
{{out}}
<pre>
Line 4,495 ⟶ 4,611:
care had to be taken with modulo 32-bit arithmetics, as PicoLisp supports only
numbers of unspecified size.
<
(load "@lib/math.l") # For 'sin'
Line 4,589 ⟶ 4,705:
(do 4 # Convert to little endian hex string
(link (pad 2 (hex (& N 255))))
(setq N (>> 8 N)) ) ) ) ) ) )</
Output:
<pre>: (md5 "")
Line 4,612 ⟶ 4,728:
Note that the following code focuses on brevity and elegance instead of performance, since Python isn't very good at number crunching anyway. If performance is important, the best solution is to use the built-in '''md5''' module, written in C.
<
rotate_amounts = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
Line 4,673 ⟶ 4,789:
for message in demo:
print(md5_to_hex(md5(message)),' <= "',message.decode('ascii'),'"', sep='')
</syntaxhighlight>
Implementation notes:
Line 4,684 ⟶ 4,800:
=={{header|Racket}}==
For an implementation of md5 in Racket see: github.com/racket/racket/blob/master/racket/collects/file/md5.rkt
<
#lang racket
(require file/md5)
(md5 #"Rosetta Code")
</syntaxhighlight>
Output:
<
#"cca1bf66b09554e10f837838c3d3efb1"
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|
<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[1]
-> uint32 \x, \n { (
($b[0] + (BEGIN Array.new:
{ ($^x +& $^z) +| ($^y +& +^$z) },
{ $^y
)[$i div
(BEGIN blob32.new: map &floor ∘
$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[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}}
Line 4,774 ⟶ 4,883:
''MD5 Message─Digest Algorithm'',
<br>April 1992.
<
@.1 = /*─────MD5 test suite [from above doc].*/
@.2 = 'a'
Line 4,887 ⟶ 4,996:
return .a(.Lr(right(d2c(_+c2d(w) + c2d(.h(x,y,z)) + c2d(!.n)),4,'0'x),m),x)
.p4: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n + 1
return .a(.Lr(right(d2c(c2d(w) + c2d(.i(x,y,z)) + c2d(!.n)+_),4,'0'x),m),x)</
{{out|output|text= when using the default input:}}
<pre>
Line 4,915 ⟶ 5,024:
Based on my Java implementation. Uses free-form RPG and a CTDATA section to hold lookup tables. Converts input from EBCDIC to ASCII before hashing.
<
Ctl-opt MAIN(Main);
Ctl-opt DFTACTGRP(*NO) ACTGRP(*NEW);
Line 5,157 ⟶ 5,266:
1700485571 2399980690 4293915773 2240044497
1873313359 4264355552 2734768916 1309151649
4149444226 3174756917 718787259 3951481745</
Sample output:
Line 5,174 ⟶ 5,283:
As with others implementations, this will not allow bit-lengths non-divisible by 8; this ability can be added in about 8 lines of code but no examples appear to be available for verification of correctness, and so it was elided.
<
#![allow(non_snake_case)] // RFC 1321 uses many capitalized variables
use std::mem;
Line 5,413 ⟶ 5,522:
assert!(md5_utf8("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == "57edf4a22be3c955ac49da2e2107b67a");
}
</syntaxhighlight>
=={{header|Scala}}==
{{trans|Java}}
Based on RFC-1321.
<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
def main(args: Array[String]): Unit = {
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].
<
include "bytedata.s7i";
include "bin32.s7i";
Line 5,470 ⟶ 5,682:
const array integer: k is createMd5Table;
var integer: length is 0;
var integer:
var integer: index is 0;
var array bin32: m is 16 times bin32.value;
Line 5,491 ⟶ 5,703:
message &:= "\0;" mult 63 - (length + 8) mod 64;
# Append length of message (before pre-processing), in bits, as 64-bit little-endian integer.
message &:=
# Process the message in successive 512-bit chunks:
# Break chunk into sixteen 32-bit little-endian words.
for index range 1 to 16 do
m[index] := bin32(bytes2Int(message[
wordIndex +:= 4;
end for;
Line 5,511 ⟶ 5,724:
elsif index <= 32 then
f := c >< (d & (b >< c));
g := succ((5 * index - 4) mod 16
elsif index <= 48 then
f := b >< c >< d;
g := succ((3 * index + 2) mod 16
else
f := c >< (b | (bin32(16#ffffffff) >< d));
g := succ((7 * pred(index)) mod 16
end if;
Line 5,534 ⟶ 5,747:
c0 +:= ord(c);
d0 +:= ord(d);
end
# Produce the final hash value:
digest :=
end func;
Line 5,559 ⟶ 5,772:
writeln("There is an error in the md5 function");
end if;
end func;</
Original source: [http://seed7.sourceforge.net/algorith/msgdigest.htm#md5]
Line 5,570 ⟶ 5,783:
=={{header|Sidef}}==
{{trans|Raku}}
<
method init {
Line 5,654 ⟶ 5,867:
for i in (range(0, M.end, 16)) {
md5_block(H, M.
}
Line 5,678 ⟶ 5,891:
say "\tHowever, that is incorrect (expected: #{md5})"
}
}</
{{out}}
<pre>
Line 5,696 ⟶ 5,909:
Original source: [//github.com/krzyzanowskim/CryptoSwift CryptoSwift]
<
import Foundation
public class MD5 {
Line 5,823 ⟶ 6,036:
}
}
</syntaxhighlight>
From-scratch implementation based on the solutions on this page without needing any external libraries:
<
let shift : [UInt32] = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21]
Line 5,908 ⟶ 6,121:
println(toHexString(md5(Array(string.utf8))))
println()
}</
{{out}}
<pre>
Line 5,935 ⟶ 6,148:
=={{header|Tcl}}==
<small>This code is extracted from the <code>md5</code> package in {{libheader|tcllib}}, and is originally due to Don Libes's transcription of the code in the MD5 specification. ''It should not be deployed in production normally; the <code>md5</code> package should be used in preference as it is usually built to be faster.</small>
<
# function calls for speed
variable ::md5::md5body {
Line 6,179 ⟶ 6,392:
format %0.2x%0.2x%0.2x%0.2x [byte0 $i] [byte1 $i] [byte2 $i] [byte3 $i]
}
}</
Demonstration code:
<
0xd41d8cd98f00b204e9800998ecf8427e ==> ""
0x0cc175b9c0f1b6a831c399e269772661 ==> "a"
Line 6,191 ⟶ 6,404:
} {
puts "“$string” -> [md5::md5 $string] (officially: $hash)"
}</
=={{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.
<
var k = [
Line 6,314 ⟶ 6,527:
var digest = md5.call(s)
Fmt.print("0x$s <== '$0s'", Fmt.v("xz", 2, digest, 0, "", ""), s)
}</
{{out}}
Line 6,332 ⟶ 6,545:
Uses DOS interrupts for display.
<
org 0x100
mov di, md5_for_display
Line 6,598 ⟶ 6,811:
test_input_6_len equ $ - test_input_6
test_input_7 db '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
test_input_7_len equ $ - test_input_7</
'''Output:'''
|