MD5/Implementation: Difference between revisions

→‎{{header|Raku}}: modernize and fix
(→‎{{header|Raku}}: add broken tag)
(→‎{{header|Raku}}: modernize and fix)
Line 4,696:
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2018.032022-07}}
<syntaxhighlight lang="raku" line>sub infix:<⊞>rotl(uint32 $a, uint32UInt $bn --> uint32) { ($a +< $bn) +&| 0xffffffff($a +> (32-$n)) }
{{Broken|raku}}
<syntaxhighlight lang="raku" line>sub infix:<⊞>(uint32 $a, uint32 $b --> uint32) { ($a + $b) +& 0xffffffff }
sub infix:«<<<»(uint32 $a, UInt $n --> uint32) { ($a +< $n) +& 0xffffffff +| ($a +> (32-$n)) }
constant FGHI = { ($^a +& $^b) +| (+^$a +& $^c) },
{ ($^a +& $^c) +| ($^b +& +^$c) },
{ $^a +^ $^b +^ $^c },
{ $^b +^ ($^a +| +^$^c) };
constant _S@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 = (floor(abs(sin($_ + 1)) * 2**32) for ^64);
(5, 9, 14, 20) xx 4,
constant @k = flat ( $_ for (4, 11, ^16, 23) xx 4,
(6, 10, 15, 21) xx 4;
constant T = (floor(abs(sin($_ + 1)) * 2**32) for ^64);
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 \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);
Blob.new: little-endian(832, 42, @H$bits);
).flat
.rotor(16)
.map({ blob32.new: @$_ })
}
sub md5-block(@blob32 $H where $H == 4, @blob32 $X where $X == 16)
{
blob32.new: $H[] Z+md5.raku
my uint32 ($A, $B, $C, $D) = @H;
reduce -> blob32 $b, $i {
($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);blob32.new:
$b[3],
($b[1] + rotl($b[0] + FGHI[$i div 16](|$b[1,2,3]) + $T[$i] + $X[@k[$i]], @S[$i])),
$b[1],
$b[2]
}, $H, |^64;
}
 
sub md5(Blob $msg --> Blobblob8)
{
blob8.new: little-endian 8, 4, |
my uint32 @M = md5-pad($msg);
reduce &md5-block,
my(constant uint32 @H$ = blob32.new: 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;),
md5-block(@H, @M[$_ .. $_+15]) for 0, 16 ...^ +@M;
my uint32 @M = |md5-pad( $msg);
Blob.new: little-endian(8, 4, @H);
}
Line 4,757 ⟶ 4,756:
'57edf4a22be3c955ac49da2e2107b67a', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
-> $expected, $msg {
my $digest = md5($msg.encode('ascii')).list».fmt('%02x').join;
is($digest, $expected, "$digest is MD5 digest of '$msg'");
}</syntaxhighlight>
1,934

edits