Bom, aqui vai uma implementação do hash SHA-1, estou trabalhando na serie SHA-2 (atualmente SHA-256 e futuramente SHA-512).
O código abaixo é para quem gosta de saber o que acontece debaixo dos panos quando você usa uma função nativa ou quando a função nativa não está disponível no seu servidor...
Pergunta
neto.joaobatista
Bom, aqui vai uma implementação do hash SHA-1, estou trabalhando na serie SHA-2 (atualmente SHA-256 e futuramente SHA-512).
O código abaixo é para quem gosta de saber o que acontece debaixo dos panos quando você usa uma função nativa ou quando a função nativa não está disponível no seu servidor...
<?php /** * Implementação PHP do Secure Hash Algorithm segundo a Secure Hash Standard (SHS) (FIPS PUB 180-3) de outubro de 2008. * <p> * Nessa primeira versão está sendo implementado apenas o hash SHA-1, a proxima versão já contará com SHA-256 * e futuramente SHA-384 e SHA-512 * </p> * * @version 0.1 * @author João Batista Neto <neto.joaobatista@gmail.com> * @since 2009-08-06 * @license LGLP * @link http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf * @category Computer Security, Cryptography, Hash. */ abstract class SecureHash { /** * Identifica o hash SHA-1 */ const SHA_1 = "sha1"; /** * Identifica o hash SHA-256 */ const SHA_256 = "sha256"; /** * Implementação do algorítimo de via única SHA-1 (Secure Hash Algorithm 1) definido pela especificação FIPS 180-3 * <p> * Message Size: < 2**64 * Block Size: 512 bits * Word Size: 32 bits * Message Digest Size: 160 bits * </p> * @link http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf * @param $message * @return string */ static public function sha1( $message ){ /** * Pre-processamento */ $M = self::pre_process( $message ); /** * Define os valores iniciais [5.3.1] */ $H = array( 0x67452301 , 0xefcdab89 , 0x98badcfe , 0x10325476 , 0xc3d2e1f0 ); /** * Calculando o Hash [6.1.2] */ for ( $i = 0 , $N = count( $M ); $i < $N; $i += 16 ){ $W = array(); /** * [6.1.2.1] */ for ( $t = 0; $t < 80; $t++ ){ $W[ $t ] = ( $t <= 15 ) ? $M[ $i + $t ] : self::ROTL( $W[ $t - 3 ] ^ $W[ $t - 8 ] ^ $W[ $t - 14 ] ^ $W[ $t - 16 ] , 1 ); } /** * [6.1.2.2] */ $a = $H[ 0 ]; $b = $H[ 1 ]; $c = $H[ 2 ]; $d = $H[ 3 ]; $e = $H[ 4 ]; /** * [6.1.2.3] */ for ( $t = 0; $t < 80; $t++ ){ $T = self::add( self::add( self::ROTL( $a , 5 ) , self::f( $t , $b , $c , $d ) ) , self::add( self::add( $e , $W[ $t ] ) , self::Kt( $t ) ) ); $e = $d; $d = $c; $c = self::ROTL( $b , 30 ); $b = $a; $a = $T; } /** * [6.1.2.4] */ $H[ 0 ] = self::add( $H[ 0 ] , $a ); $H[ 1 ] = self::add( $H[ 1 ] , $b ); $H[ 2 ] = self::add( $H[ 2 ] , $c ); $H[ 3 ] = self::add( $H[ 3 ] , $d ); $H[ 4 ] = self::add( $H[ 4 ] , $e ); } return ( sprintf( "%08x%08x%08x%08x%08x" , $H[ 0 ] , $H[ 1 ] , $H[ 2 ] , $H[ 3 ] , $H[ 4 ] ) ); } /** * Pre-processamento [5] * @return array */ static private function pre_process( $message ){ $size = strlen( $message ); $M = array(); $N = ( ( $size + 8 ) >> 6 ) + 1; /** * [5.1.1] */ $message .= "x80"; for ( $i = 0; $i < $N * 16; $i++ ) $M[ $i ] = 0; for ( $i = 0; $i < $size; $i++ ) $M[ $i >> 2 ] |= ord( $message{ $i } ) << ( 24 - ( $i % 4 ) * 8 ); $M[ $i >> 2 ] |= 0x80 << ( 24 - ( $i % 4 ) * 8 ); $M[ $N * 16 - 1 ] = $size * 8; return( $M ); } /** * Operação AND [3.2.2] * Z = (X + Y) mod 2^32 * @param integer $x * @param integer $y * @return integer O novo valor */ static private function add( $x , $y ){ $lsw = ( $x & 0xffff ) + ( $y & 0xffff ); $msw = ( $x >> 16 ) + ( $y >> 16 ) + ( $lsw >> 16 ); return ( ( $msw << 16 ) | ( $lsw & 0xFFFF ) ); } /** * Operação Right Shift [3.2.3] * @param $x * @param $n * @return integer */ static private function SHR( $x , $n ){ $z = hexdec( 80000000 ); if ( $z & $x ){ $x = ( $x >> 1 ); $x &= ~$z; $x |= 0x40000000; $x = ( $x >> ( $n - 1 ) ); } else { $x = ( $x >> $n ); } return( $x ); } /** * Operação Circular Right Shift [3.2.4] * @param integer $x * @param integer $n * @return integer */ static private function ROTR( $x , $n ){ return( ( self::SHR( $x , $n ) | ( $x << ( 32 - $n ) ) & 0xFFFFFFFF ) ); } /** * Operação Circular Left Shift [3.2.5] * @param integer $num * @param integer $n * @return integer */ static private function ROTL( $x , $n ){ return ( ( $x << $n ) | self::SHR( $x , 32 - $n ) ); } /** * Função f [4.1.1] * @param $t * @param $b * @param $c * @param $d * @return integer */ static private function f( $t , $b , $c , $d ){ if ( ( $t >= 0 ) && ( $t <= 19 ) ) return ( self::Ch( $b , $c , $d ) ); if ( ( $t >= 20 ) && ( $t <= 39 ) ) return ( self::Parity( $b , $c , $d ) ); if ( ( $t >= 40 ) && ( $t <= 59 ) ) return ( self::Maj( $b , $c , $d ) ); if ( ( $t >= 60 ) && ( $t <= 79 ) ) return ( self::Parity( $b , $c , $d ) ); } /** * Ch [4.1.1] * @param integer $x * @param integer $y * @param integer $z * @return integer */ static private function Ch( $x , $y , $z ){ return ( ( $x & $y ) ^ ( ~$x & $z ) ); } /** * Parity [4.1.1] * @param integer $x * @param integer $y * @param integer $z * @return integer */ static private function Parity( $x , $y , $z ){ return ( $x ^ $y ^ $z ); } /** * Maj [4.1.1] * @param integer $x * @param integer $y * @param integer $z * @return integer */ static private function Maj( $x , $y , $z ){ return ( ( $x & $y ) ^ ( $x & $z ) ^ ( $y & $z ) ); } /** * Sigma{256} 0 [4.1.2] * @param integer $x * @return integer */ static private function Sigma_0( $x ){ return( ( self::ROTR( $x , 2 ) ^ self::ROTR( $x , 13 ) ^ self::ROTR( $x , 22 ) ) ); } /** * Sigma{256} 1 [4.1.2] * @param integer $x * @return integer */ static private function Sigma_1( $x ){ return( ( self::ROTR( $x , 6 ) ^ self::ROTR( $x , 11 ) ^ self::ROTR( $x , 25 ) ) ); } /** * sigma{256} 0 [4.1.2] * @param integer $x * @return integer */ static private function sigma0( $x ){ return( ( self::ROTR( $x , 7 ) ^ self::ROTR( $x , 18 ) ^ ( self::SHR( $x , 3 ) ) ) ); } /** * sigma{256} 1 [4.1.2] * @param integer $x * @return integer */ static private function sigma1( $x ){ return( ( self::ROTR( $x , 17 ) ^ self::ROTR( $x , 19 ) ^ ( self::SHR( $x , 10 ) ) ) ); } /** * Recupera o valor da constante Kt [4.2.1] e [4.2.2] * @param integer $t * @param string $type * @return integer */ static private function Kt( $t , $type = self::SHA_1 ){ /** * Kt [4.2.1] */ $k_SHA1 = array( 0x5a827999 , 0x6ed9eba1 , 0x8f1bbcdc , 0xca62c1d6 ); /** * Kt [4.2.2] */ $k_SHA256 = array( 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ); /** * Retorna a constante segundo o hash usado */ switch ( $type ){ case self::SHA_1 : if ( ( $t >= 0 ) && ( $t <= 19 ) ) return ( $k_SHA1[ 0 ] ); if ( ( $t >= 20 ) && ( $t <= 39 ) ) return ( $k_SHA1[ 1 ] ); if ( ( $t >= 40 ) && ( $t <= 59 ) ) return ( $k_SHA1[ 2 ] ); if ( ( $t >= 60 ) && ( $t <= 79 ) ) return ( $k_SHA1[ 3 ] ); throw new UnexpectedValueException( sprintf( "O valor %08x não era esperado." , $t ) ); case self::SHA_256: return( $k_SHA256[ $t ] ); } } }Agora fazendo o cálculo:A saída será:
nativo: f0c8faeacb1df5cebc50c63d1d9aef0f0266535d
SHA-1: f0c8faeacb1df5cebc50c63d1d9aef0f0266535d
Link para o comentário
Compartilhar em outros sites
0 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.