<?
class SHA1_blizzard
{
    public 
$h;
    private 
$pending;
    
    function 
SHA1_blizzard()
    {
        
$this->init();
    }
    
    function 
init()
    {
        
$this->h[0] = (int)0x67452301;
        
$this->h[1] = (int)0xefcdab89;
        
$this->h[2] = (int)0x98badcfe;
        
$this->h[3] = (int)0x10325476;
        
$this->h[4] = (int)0xc3d2e1f0;
    }
    
    
# $str MUST be 512 bits
    
function hash_chunk($str)
    {
        
# Unpack chunk into 32-bit LITTLE-ENDIAN blocks, then
        # re-base them to 0.
        # NOTE: Blizzard interprets the data as little-endian words,
        # while proper SHA1 uses big-endian.
        
$W unpack("V*"$str);
        for (
$x 0$x 16$x++)
            
$W[$x] = $W[$x 1];

        
# expand 512 input bits into an additional 2048 bits
        # NOTE: Blizzard has the operands of this rotate left operation
        # flipped vs. proper SHA1.
        
for ($x 16$x 80$x++)
            
$W[$x] = $this->rl(1$W[$x 3] ^ $W[$x 8] ^ $W[$x 14] ^ $W[$x 16]);

        
$a $this->h[0];
        
$b $this->h[1];
        
$c $this->h[2];
        
$d $this->h[3];
        
$e $this->h[4];

        for (
$x 0$x 80$x++) {
            if (
$x 20)        $T = (($b $c) | (~$b $d)) + 0x5a827999;
            else if (
$x 40)    $T = ($b $c $d) + 0x6ed9eba1;
            else if (
$x 60)    $T = (($b $c) | ($b $d) | ($c $d)) + 0x8f1bbcdc;
            else if (
$x 80)    $T = ($b $c $d) + 0xca62c1d6;

            
$T += $this->rl($a5) + $e $W[$x];
            
            
$e $d;
            
$d $c;
            
$c $this->rl($b30);
            
$b $a;
            
$a $T 0xffffffff;
        }

        
$this->h[0] = ($this->h[0] + $a) & 0xffffffff;
        
$this->h[1] = ($this->h[1] + $b) & 0xffffffff;
        
$this->h[2] = ($this->h[2] + $c) & 0xffffffff;
        
$this->h[3] = ($this->h[3] + $d) & 0xffffffff;
        
$this->h[4] = ($this->h[4] + $e) & 0xffffffff;
    }

    function 
add($data)
    {
        
$need 64 strlen($this->pending);
        
        do {
            if (
$need == 0) {
                
$this->hash_chunk($this->pending);
                
$this->pending '';
                
$need 64;
            }
            
            
$this->pending .= substr($data0$need);
            
$data substr($data$need);

            
$need 64 strlen($this->pending);
        } while (
$need == 0);
    }
    
    function 
finish()
    {
        
# if we have pending data, pad out this chunk
        
if (strlen($this->pending)) {
            
$this->hash_chunk(str_pad($this->pending64"\0"));
            
$this->pending '';
        }
        
        return 
$this->hexdigest();
    }
    
    function 
hexdigest()
    {
        return 
sprintf("%08x%08x%08x%08x%08x"$this->h[0], $this->h[1], $this->h[2], $this->h[3], $this->h[4]);
    }
    
    function 
rl($value$bits)
    {
        
$value &= 0xffffffff;
        
# NOTE: this both depends on and works around sign extension.
        # We must truncate $bits because Blizzard's code has the
        # operands reversed.
        
$left $value << ($bits 31);
        
$right $value >> ((-$bits) & 31);
        
$right &= (<< ($bits 31)) - 1;
        
        return (
$left $right);
    }
}
$bah = new SHA1_blizzard;
$bah->add($_REQUEST['in']);
printf("%s\n"$bah->finish());

?>