SHA-1 or SHA1 is a one-way hash function;
it computes a 160-bit message digest.
SHA-1 often appears in security protocols; for example,
many HTTPS websites use RSA with SHA-1 to secure their connections.
BitTorrent uses SHA-1 to verify downloads.
Git and Mercurial use SHA-1 digests to identify commits.

A US government standard, FIPS 180-1, defines SHA-1.

Find the SHA-1 message digest for a string of octets. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code.



 Warning: SHA-1 has known weaknesses. Theoretical attacks may find a collision after 252 operations, or perhaps fewer.
This is much faster than a brute force attack of 280 operations. USgovernment deprecated SHA-1.
For production-grade cryptography, users may consider a stronger alternative, such as SHA-256 (from the SHA-2 family) or the upcoming SHA-3.


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';