MD5/Implementation: Difference between revisions

Content deleted Content added
Edwin (talk | contribs)
m →‎{{header|Perl 6}}: Some tweaks for readability.
Edwin (talk | contribs)
m →‎{{header|Perl 6}}: several tweaks, bring naming closer to RFC 1321, return digest as Buf.
Line 1,715:
<lang perl6>use Test;
 
sub postfixprefix:<mod2³²¬>(\x) { (+^ x) % 2**32 }
sub prefixinfix:<¬>(\x, \y) { (x +^ xy)mod2³² % 2**32 }
sub infix:«<⊞><<»(\x, \yn) { (x {+< n) % 2**32 +| (x +> y(32-n))mod2³² }
sub infix:«<<<»(\x, \n) { (x +< n)mod2³² +| (x +> (32-n)) }
 
subconstant FGHI = -> F(\X, \Y, \Z) { (X +& Y) +| (¬X +& Z) },
sub G( -> \X, \Y, \Z) { (X +& Z) +| (Y +& ¬Z) },
sub H( -> \X, \Y, \Z) { X +^ Y +^ Z },
sub I( -> \X, \Y, \Z) { Y +^ (X +| ¬Z) };
 
myconstant @rS = (7, 12, 17, 22,) 7,xx 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 224,
5, 9, 14, 20, (5, 9, 14, 20,) 5,xx 9, 14, 20, 5, 9, 14, 204,
4, 11, 16, 23, (4, 11, 16, 23,) 4, 11, 16, 23,xx 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, (6, 10, 15, 21,) 6,xx 10, 15, 214;
 
myconstant @kT = (floor(abs(sin($_ + 1)) * 2**32) for 0..63^64);
 
constant k = ( $_ for ^16),
((5*$_ + 1) % 16 for ^16),
((3*$_ + 5) % 16 for ^16),
((7*$_ ) % 16 for ^16);
 
sub little-endian($w, $n, *@v) { (@v X+> ($w X* ^$n)) X% (2 ** $w) }
 
sub md5-pad(Buf $msg)
Line 1,736 ⟶ 1,742:
my \bits = 8 * $msg.elems;
my @padded = $msg.list, 0x80, 0x00 xx (-(bits div 8 + 1 + 8) % 64);
@padded.map({ :256[$^d,$^c,$^b,$^a] }), little-endian(bits)mod2³²32, 2, (bits +> 32)mod2³²;
}
 
sub md5-block(@H is rw, @MX)
{
my ($A, $B, $C, $D) = @H;
for 0..63^64 -> \i {
my \f = FGHI[i div 16]($fB, $C, $gD);
($A, $B, $C, $D)
given i {
when 0..15 { $f = F($BD, $C,$D);B ⊞ (($g =A f T[i] @X[k[i]]) <<< S[i]), $B, }$C);
when 16..31 { $f = G($B,$C,$D); $g = (5*i + 1) % 16 }
when 32..47 { $f = H($B,$C,$D); $g = (3*i + 5) % 16 }
when 48..63 { $f = I($B,$C,$D); $g = (7*i ) % 16 }
}
($A, $B, $C, $D) = ($D, $B ⊞ (($A ⊞ $f ⊞ @k[i] ⊞ @M[$g]) <<< @r[i]), $B, $C);
}
@H «⊞=» ($A, $B, $C, $D);
}
 
sub md5-hex(Buf $msg --> StrBuf)
{
my @M = md5-pad($msg);
my @H = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
md5-block(@H, @M[$_ .. $_+15]) for 0, 16 ...^ +@M;
Buf.new: little-endian(8, 4, @H);
((@H X+> (0, 8, 16, 24)) «%» 256)».fmt('%02x').join;
}
 
for 'd41d8cd98f00b204e9800998ecf8427e', ""'',
'0cc175b9c0f1b6a831c399e269772661', "'a"',
'900150983cd24fb0d6963f7d28e17f72', "'abc"',
'f96b697d7cb7938d525a2f31aaf161d0', "'message digest"',
'c3fcd3d76192e4007dfb496cca67e13b', "'abcdefghijklmnopqrstuvwxyz"',
'd174ab98d277d9f5a5611c2c9f419d9f', "'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"',
'57edf4a22be3c955ac49da2e2107b67a', "'12345678901234567890123456789012345678901234567890123456789012345678901234567890"'
-> $expected, $msg {
my $digest = md5-hex($msg.encode('ascii')).list».fmt('%02x').join;
is($digest, $expected, "$digest is MD5 digest of '$msg'");
}</lang>