MD5/Implementation: Difference between revisions

Line 4,814:
(formerly Perl 6)
{{works with|rakudo|2022-07}}
<syntaxhighlight lang="raku" line>proto md5($msg) -->returns blob8)Blob is export {*}
multi md5(Str $strmsg) { samewithmd5 $strmsg.encode }
multi md5(Blob $msg) {
sub rotl(uint32 $a\x, UInt $\n) -->returns uint32) { ($ax +< $n) +| ($ax +> (32-$n)) }
 
constant FGHI = { ($^a +& $^b) +| (+^$a +& $^c) },
{ ($^a +& $^c) +| ($^b +& +^$c) },
{ $^a +^ $^b +^ $^c },
{ $^b +^ ($^a +| +^$^c) };
 
constant @S = flat < 7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21 >.rotor(4) X[xx] 4;
constant @T = ^64 .map: { floor(abs(sin($_ + 1)) * 2**32) }
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) { (@v X+> flat ($w X* ^$n)) X% (2 ** $w) }
my $\bits = 8 * $msg.elems;
 
Blob.new: little-endian(32 8, 24, $bits)
sub md5-pad(blob8 $msg)
|reduce -> blob32Blob $bblob, blob32 $iX {
{
blob32.new: $H[]blob Z+
my $bits = 8 * $msg.elems;
reduce -> $b, $i {
(
blob32.new:
(flat $msg.list, 0x80, 0x00 xx -($bits div 8 + 1 + 8) % 64)
.map({ :256[ $^d,$^c,$^b,$^a[3] }),
$b[1] + rotl(
little-endian(32, 2, $bits)
$b[0] + (BEGIN Array.new:
).flat
constant FGHI = { ($^ax +& $^by) +| (+^$ax +& $^cz) },
.rotor(16)
.map( { blob32.new:($^x +& @$_^z) }+| ($^y +& +^$z) },
{ $^ax +^ $^by +^ $^c z },
}
{ ($^ay +& $^c) +| ($^bx +&| +^$c^z) },
 
)[$i div 16](|$b[1..3]) +
sub md5-block(blob32 $H where 4, blob32 $X where 16)
(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]],
blob32.new: $H[] Z+
constant @S = (BEGIN flat < 7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21 >.rotor(4) X[xx]Xxx 4;)[$i]
reduce -> blob32 $b, $i {
}, $H, |^64; ),
blob32.new:
$b[31],
$b[2]
($b[1] + rotl($b[0] + FGHI[$i div 16](|$b[1,2,3]) + @T[$i] + $X[@k[$i]], @S[$i])),
}, $blob, |^64;
$b[1],
$b[2] },
(constant $ =BEGIN blob32.new: 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476),
}, $H, |^64;
|map { blob32.new: @$_ },
}
blob32.new(flat (@$msg.list, 0x80, 0x00 xx (-($bits div 8 + 1 + 8) % 64))
 
blob8 .newrotor(4).map({ :256[@^a.reverse] }), little-endian 8(32, 42, |bits)
reduce &md5-block, )
.rotor(16);
(constant $ = blob32.new: 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476),
|md5-pad $msg;
}
CHECK {
use Test;
plan 7;
 
for 'd41d8cd98f00b204e9800998ecf8427e', '',
'0cc175b9c0f1b6a831c399e269772661', 'a',
'900150983cd24fb0d6963f7d28e17f72', 'abc',
'f96b697d7cb7938d525a2f31aaf161d0', 'message digest',
Line 4,878 ⟶ 4,863:
is($digest, $expected, "$digest is MD5 digest of '$msg'");
}
done-testing;
}</syntaxhighlight>
 
1,934

edits