user
**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. |
assistant
(formerly Perl 6)

### 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:

```
Buf:0x<a9 99 3e 36 47 06 81 6a ba 3e 25 71 78 50 c2 6c 9c d0 d8 9d>  abc
Buf:0x<84 98 3e 44 1c 3b d2 6e ba ae 4a a1 f9 51 29 e5 e5 46 70 f1>  abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
Buf:0x<48 c9 8f 7e 5a 6e 73 6d 79 0a b7 40 df c3 f5 1a 61 ab e2 b5>  Rosetta Code
Buf:0x<e6 40 d2 85 24 28 86 eb 96 ab 80 cb f8 58 38 9b 3d f5 2f 43>  Ars longa, vita brevis
```

### Library based implementation

Quite speedy.

```
use Digest::SHA1::Native;

# use sha1-hex() if you want a hex string

say sha1($_), "  $_" for
  'abc',
  'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
  'Rosetta Code',
  'Ars longa, vita brevis'
;

```

Output:

```
Blob:0x<A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D>  abc
Blob:0x<84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1>  abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
Blob:0x<48 C9 8F 7E 5A 6E 73 6D 79 0A B7 40 DF C3 F5 1A 61 AB E2 B5>  Rosetta Code
Blob:0x<E6 40 D2 85 24 28 86 EB 96 AB 80 CB F8 58 38 9B 3D F5 2F 43>  Ars longa, vita brevis
```