SHA-1
Pure Raku
A pure Raku implementation that closely follows the description of SHA-1 in FIPS 180-1. Slow.
sub postfix:<mod2³²> { $^x % 2**32 }
sub infix:<⊕> { ($^x + $^y)mod2³² }
sub S { ($^x +< $^n)mod2³² +| ($x +> (32-$n)) }
my \f = -> \B,\C,\D { (B +& C) +| ((+^B)mod2³² +& D) },
-> \B,\C,\D { B +^ C +^ D },
-> \B,\C,\D { (B +& C) +| (B +& D) +| (C +& D) },
-> \B,\C,\D { B +^ C +^ D };
my \K = 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6;
sub sha1-pad(Blob $msg)
{
my \bits = 8 * $msg.elems;
my @padded = flat $msg.list, 0x80, 0x00 xx (-($msg.elems + 1 + 8) % 64);
flat @padded.map({ :256[$^a,$^b,$^c,$^d] }), (bits +> 32)mod2³², (bits)mod2³²;
}
sub sha1-block(@H, @M is copy)
{
@M.push: S(1, [+^] @M[$_ «-« <3 8 14 16>] ) for 16 .. 79;
my ($A,$B,$C,$D,$E) = @H;
for 0..79 -> \t {
($A, $B, $C, $D, $E) =
S(5,$A) ⊕ f[t div 20]($B,$C,$D) ⊕ $E ⊕ @M[t] ⊕ K[t div 20],
$A, S(30,$B), $C, $D;
}
@H »⊕=« ($A,$B,$C,$D,$E);
}
sub sha1(Blob $msg) returns Blob
{
my @M = sha1-pad($msg);
my @H = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0;
sha1-block(@H,@M[$_..$_+15]) for 0, 16...^ +@M;
Blob.new: flat map { reverse .polymod(256 xx 3) }, @H;
}
say sha1(.encode('ascii')), " $_"
for 'abc',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
'Rosetta Code',
'Ars longa, vita brevis';Output:
Library based implementation
Quite speedy.
Output:
Last updated
Was this helpful?