package Mail::SpamAssassin::SHA1;
require 5.002;
use strict;
use bytes;
use integer;
use vars qw(
@ISA @EXPORT
);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(sha1);
use constant HAS_DIGEST_SHA1 => eval { require Digest::SHA1; };
sub sha1 {
my ($data) = @_;
if (HAS_DIGEST_SHA1) {
return Digest::SHA1::sha1_hex($data);
}
else {
return SHA1($data);
}
}
sub SHA1($) {
local $^W = 0;
local $_;
my @a = (16..19); my @b = (20..39); my @c = (40..59); my @d = (60..79);
my $data = $_[0];
my $aa = 0x67452301; my $bb = 0xefcdab89; my $cc = 0x98badcfe;
my $dd = 0x10325476; my $ee = 0xc3d2e1f0;
my ($a, $b, $c, $d, $e, $t, $l, $r, $p) = (0)x9;
my @W;
do {
$_ = substr $data, $l, 64;
$l += ($r = length);
$r++, $_.="\x80" if ($r<64 && !$p++); @W = unpack "N16", $_."\0"x7; $W[15] = $l*8 if ($r<57);
$a=$aa, $b=$bb, $c=$cc, $d=$dd, $e=$ee;
for(@W){
$t = ($b&($c^$d)^$d) + $e + $_ + 0x5a827999 + ($a<<5|31&$a>>27);
$e = $d; $d = $c; $c = $b<<30 | 0x3fffffff & $b>>2; $b = $a; $a = $t;
}
for(@a){
$t = $W[$_-3]^$W[$_-8]^$W[$_-14]^$W[$_-16];
$W[$_] = $t = ($t<<1|1&$t>>31);
$t += ($b&($c^$d)^$d) + $e + 0x5a827999 + ($a<<5|31&$a>>27);
$e = $d; $d = $c; $c = $b<<30 | 0x3fffffff & $b>>2; $b = $a; $a = $t;
}
for(@b){
$t = $W[$_-3]^$W[$_-8]^$W[$_-14]^$W[$_-16];
$W[$_] = $t = ($t<<1|1&$t>>31);
$t += ($b^$c^$d) + $e + 0x6ed9eba1 + ($a<<5|31&$a>>27);
$e = $d; $d = $c; $c = $b<<30 | 0x3fffffff & $b>>2; $b = $a; $a = $t;
}
for(@c){
$t = $W[$_-3]^$W[$_-8]^$W[$_-14]^$W[$_-16];
$W[$_] = $t = ($t<<1|1&$t>>31);
$t += ($b&$c|($b|$c)&$d) + $e + 0x8f1bbcdc + ($a<<5|31&$a>>27);
$e = $d; $d = $c; $c = $b<<30 | 0x3fffffff & $b>>2; $b = $a; $a = $t;
}
for(@d){
$t = $W[$_-3]^$W[$_-8]^$W[$_-14]^$W[$_-16];
$W[$_] = $t = ($t<<1|1&$t>>31);
$t += ($b^$c^$d) + $e + 0xca62c1d6 + ($a<<5|31&$a>>27);
$e = $d; $d = $c; $c = $b<<30 | 0x3fffffff & $b>>2; $b = $a; $a = $t;
}
$aa+=$a, $bb+=$b, $cc+=$c, $dd+=$d, $ee+=$e;
} while $r>56;
sprintf "%.8x%.8x%.8x%.8x%.8x", $aa & 0xffffffff, $bb & 0xffffffff, $cc & 0xffffffff, $dd & 0xffffffff, $ee & 0xffffffff;
}
1;