<?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); }}?>