php版 tea 加密

来源:互联网 发布:中控网络考勤机 编辑:程序博客网 时间:2024/06/06 09:27
<?php/** * php 版的tea 加密算法,提供附件上传和下载的加密,解密功能 * 包括  encrypt 加密  decrypt 解密    setkey 设置密钥 * 在解密的时候需要 设置加密是补齐的位移量,避免出现多余乱码   加密轮数 推荐8的倍数,为16或者32,php为弱语言类型,必须限定它的整型范围,字节序采用Little Endian 低位字节序 *//*$key = '%9^q69LE$Omg:ion';$t = new tea();$jmstr = $t->readstr();$jiami = $t->encrypt($jmstr, $key);//$yc = strlen($date); 原长度//$bj = 8-$yc%8;//$t->setSign($bj);$jimi = $t->decrypt($jiami, $key);$zh = strlen($jimi);$bj = $t->getSign();//$t->writestr(substr($jimi,$bj,$zh));*/class tea {    private $a, $b, $c, $d;    private $n_iter,$sign;    public function __construct() {        $this->setIter ( 16 );    }    private function setIter($n_iter) {        $this->n_iter = $n_iter;    }    private function getIter() {        return $this->n_iter;    }    public function setSign($sign)    {    return $this->sign=$sign;    }    public function getSign()    {    return $this->sign;    }    public function encrypt($data, $key) {        $sign = 8-strlen($data)%8;//此值为需要补齐的8的倍数值  重点           $n = $this->_resize ( $data, 8 );                $data_long [0] = $sign; //加密的第一位,此值为需要补齐的8的倍数值       // $this->setSign($sign);         // 重点 格式化数据 按照 Little—Endian 顺序        $n_data_long = $this->_str2long ( 1, $data, $data_long );         // 格式化 key 到128位16个字节 一个字节8位        $this->_resize ( $key, 16, true );         if ('' == $key)            $key = '0000000000000000';                   // convert key to long        $n_key_long = $this->_str2long ( 0, $key, $key_long );// 重点              // encrypt the long data with the key        $enc_data = '';        $w = array (0, 0 );        $j = 0;        $k = array (0, 0, 0, 0 );                for($i = 0; $i < $n_data_long; $i=$i+2) { //n_data_long 为一个整型的 数据数组长度值 这个数组是存放着 转换之后的 数据值            // get next key part of 128 bits            if ($j + 4 <= $n_key_long) {                $k [0] = $key_long [$j];                $k [1] = $key_long [$j + 1];                $k [2] = $key_long [$j + 2];                $k [3] = $key_long [$j + 3];            }            $this->_encipherLong ( $data_long [$i], $data_long [$i+1], $w, $k );                       // append the enciphered longs to the result            $enc_data .= $this->_long2str ( $w [0] );            $enc_data .= $this->_long2str ( $w [1] );        }               return $enc_data;    }    public function decrypt($enc_data, $key) {        // convert data to long        $n_enc_data_long = $this->_str2long ( 0, $enc_data, $enc_data_long );               // resize key to a multiple of 128 bits (16 bytes)        $this->_resize ( $key, 16, true );        if ('' == $key)            $key = '0000000000000000';                   // convert key to long        $n_key_long = $this->_str2long ( 0, $key, $key_long );                // decrypt the long data with the key        $data = '';        $w = array (0, 0 );        $j = 0;        $len = 0;        $k = array (0, 0, 0, 0 );        $pos = 0;               for($i = 0; $i < $n_enc_data_long; $i += 2) {            // get next key part of 128 bits            if ($j + 4 <= $n_key_long) {                $k [0] = $key_long [$j];                $k [1] = $key_long [$j + 1];                $k [2] = $key_long [$j + 2];                $k [3] = $key_long [$j + 3];            }                      $this->_decipherLong ( $enc_data_long [$i], $enc_data_long [$i + 1], $w, $k );           if($i==0)            {              $this->setSign($w [0]);//截取补出来的空位            }          $data .= $this->_long2str ( $w [0] );          $data .= $this->_long2str ( $w [1] );        }                     return $data;    }    private function _encipherLong($y, $z, &$w, &$k) {        $sum = ( integer ) 0;        $delta = 0x9e3779b9;                $n = ( integer ) $this->n_iter;        $bjz_int = PHP_INT_MAX; //整型的边界值        while ( $n -- > 0 ) {        $sum += $delta;                $y += (($z << 4) + $k[0]) ^ ($z + $sum) ^ (($z >> 5) + $k[1]);                    if($y <= -$bjz_int)// 调整位移值的关键值            {            $y=$y+4294967296;            }            else if($y >= $bjz_int)            {            $y=$y-4294967296;            }                           $z += (($y << 4) + $k[2]) ^ ($y + $sum) ^ (($y >> 5) + $k[3]);        // 调整位移值的关键值            if($z <= -$bjz_int)    {    $z=$z+4294967296;    }    else if($z >= $bjz_int)    {    $z=$z-4294967296;    }        }        $w [0] = $y;        $w [1] = $z;    }    private function _decipherLong($y, $z, &$w, &$k) {        // sum = delta<<5, in general sum = delta * n        $n = ( integer ) $this->n_iter;                 $delta = 0x9E3779B9;        if($n==16)        {           $sum = 0xE3779B90;        }        else if($n==32)        {        $sum = 0xC6EF3720;        }        else         {        $sum = $delta * $n;        }         $bjz_int = PHP_INT_MAX; //整型的边界值        while ( $n -- > 0 ) {             $wy=$y+$sum;// 位移调整量           if($wy>=$bjz_int)        {        $wy = $wy-4294967296;        }        else if($wy<=-$bjz_int)        {        $wy = $wy+4294967296;        }        $z -= (($y << 4) + $k[2]) ^ ($wy) ^ (($y >> 5) + $k[3]);            // 调整位移值的关键值            if($z<=-$bjz_int)    {    $z = $z+4294967296;    }    else if($z>=$bjz_int)    {    $z = $z-4294967296;    }                 $wz = $z+$sum;// 位移调整量             if($wz>=$bjz_int)           {         $wz = $wz-4294967296;           }           else if($wz<=-$bjz_int)           {         $wz = $wz+4294967296;           }    $y -= (($z << 4) + $k[0]) ^ ($wz) ^ (($z >> 5) + $k[1]);        // 调整位移值的关键值   if($y<=-$bjz_int)    {    $y = $y+4294967296;    }    else if($y>=$bjz_int)    {    $y = $y-4294967296;    }        $sum -= $delta;            if($sum>=$bjz_int)//调整sum步数    {    $sum = $sum-4294967296;    }    else if ($sum<=-$bjz_int)    {    $sum = $sum+4294967296;    }            }                    $w [0] = $y;        $w [1] = $z;    }    private function _resize(&$data, $size, $nonull = false) {        $dach='';// 重点    $n = strlen ( $data );      if($data=='%9^q69LE$Omg:ion')//修改密钥    //if($data=='lzm0FfyAtjAOc6:y')//修改密钥    {    $nmod = $n % $size;    }    else {    $nmod = 8-$n%$size-4;    }            if($nmod>0)//大于0 就补齐空位         {         for($i=0;$i<$nmod;$i++)            {              $dach .= chr(0);//为了测试写为固定值            }          $data = $dach.$data; //补齐空位 方便移位         }        return $n;    }       private function _str2long($start, &$data, &$data_long) {            $n = strlen ( $data );                $tmp = unpack ( 'V*', $data );//无符号长整形 高位在前 低位在后                $j = $start;               foreach ( $tmp as $value )        {           $data_long [$j ++] = $value;        }                return $j;    }    private function _long2str($l) {        return pack ( 'V', $l );    }  //记录日志的函数  function writelog($str)  {    $showtime = date("Y-m-d H:i:s");$file = "/home/nemo/data/jmlog/jmlog.log";$file_pointer = fopen($file,"a");fwrite($file_pointer,$showtime." #5880 Message: ");fwrite($file_pointer,$str."\r\n");fclose($file_pointer);    }  //读文件   function readstr() {$fpath = "/home/nemo/apache/htdocs/tea/sysbian.txt";$ftext = file_get_contents($fpath);return $ftext;   }// 写文件   function writestr($str) {$fpath = "/home/nemo/apache2/htdocs/tea/sysbian.txt";$fp = fopen ( $fpath, 'a' );fwrite ( $fp, $str );fclose ( $fp );  }  //提供函数的计算时间    function get_microtime(){         list($usec, $sec) = explode(' ', microtime());         return ((float)$usec + (float)$sec);  }}?>

原创粉丝点击