xxtea加密算法的PHP實現

<?php
/*
* xtea加密算法
*/


class XxTea {

   /**
    * 加密方法
    *
    * @param string $str    須要加密的內容
    * @param string $key    密鑰
    * @param bool $toBase64  是否base64(最好true吧,好比cookie加密長度有限制的)
    * return string
    */

   public function encrypt($str, $key, $toBase64= true) {
     if ($str == "") {
       return "";
    }
    $v = $ this->_str2long ( $str, true );
    $k = $ this->_str2long ( $key, false );
     if (count ( $k ) < 4) {
       for($i = count ( $k ); $i < 4; $i ++) {
        $k [$i] = 0;
      }
    }
    $n = count ( $v ) - 1;
    
    $z = $v [$n];
    $y = $v [0];
    $delta = 0x9E3779B9;
    $q = floor ( 6 + 52 / ($n + 1) );
    $sum = 0;
     while ( 0 < $q -- ) {
      $sum = $ this->_int32 ( $sum + $delta );
      $e = $sum >> 2 & 3;
       for($p = 0; $p < $n; $p ++) {
        $y = $v [$p + 1];
        $mx = $ this->_int32 ( (($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4) ) ^ $ this->_int32 ( ($sum ^ $y) + ($k [$p & 3 ^ $e] ^ $z) );
        $z = $v [$p] = $ this->_int32 ( $v [$p] + $mx );
      }
      $y = $v [0];
      $mx = $ this->_int32 ( (($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4) ) ^ $ this->_int32 ( ($sum ^ $y) + ($k [$p & 3 ^ $e] ^ $z) );
      $z = $v [$n] = $ this->_int32 ( $v [$n] + $mx );
    }
     if ($toBase64) {
       return base64_encode($ this->_long2str ( $v, false ));
    }
     return $ this->_long2str ( $v, false );
  }

   /**
    * 解密方法
    *
    * @param string $str    加密後的內容
    * @param string $key    密鑰
    * @param bool $toBase64  
    * return string
    */

   public function decrypt($str, $key, $toBase64= true) {
     if ($str == "") {
       return "";
    }
    $toBase64 && $str = base64_decode($str);
    $v = $ this->_str2long ( $str, false );
    $k = $ this->_str2long ( $key, false );
     if (count ( $k ) < 4) {
       for($i = count ( $k ); $i < 4; $i ++) {
        $k [$i] = 0;
      }
    }
    $n = count ( $v ) - 1;
    
    $z = $v [$n];
    $y = $v [0];
    $delta = 0x9E3779B9;
    $q = floor ( 6 + 52 / ($n + 1) );
    $sum = $ this->_int32 ( $q * $delta );
     while ( $sum != 0 ) {
      $e = $sum >> 2 & 3;
       for($p = $n; $p > 0; $p --) {
        $z = $v [$p - 1];
        $mx = $ this->_int32 ( (($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4) ) ^ $ this->_int32 ( ($sum ^ $y) + ($k [$p & 3 ^ $e] ^ $z) );
        $y = $v [$p] = $ this->_int32 ( $v [$p] - $mx );
      }
      $z = $v [$n];
      $mx = $ this->_int32 ( (($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4) ) ^ $ this->_int32 ( ($sum ^ $y) + ($k [$p & 3 ^ $e] ^ $z) );
      $y = $v [0] = $ this->_int32 ( $v [0] - $mx );
      $sum = $ this->_int32 ( $sum - $delta );
    }
     return $ this->_long2str ( $v, true );
  }

   /**
    * 長整型轉爲字符串
    *
    * @param long $v
    * @param boolean $w
    * @return string
    */

   private function _long2str($v, $w) {
    $len = count ( $v );
    $n = ($len - 1) << 2;
     if ($w) {
      $m = $v [$len - 1];
       if (($m < $n - 3) || ($m > $n))
         return false;
      $n = $m;
    }
    $s = array ();
     for($i = 0; $i < $len; $i ++) {
      $s [$i] = pack ( "V", $v [$i] );
    }
     if ($w) {
       return substr ( join ( '', $s ), 0, $n );
    } else {
       return join ( '', $s );
    }
  }

   /**
    * 字符串轉爲長整型
    *
    * @param string $s
    * @param boolean $w
    * @return Ambigous <multitype:, number>
    */

   private function _str2long($s, $w) {
    $v = unpack ( "V*", $s . str_repeat ( "\0", (4 - strlen ( $s ) % 4) & 3 ) );
    $v = array_values ( $v );
     if ($w) {
      $v [count ( $v )] = strlen ( $s );
    }
     return $v;
  }
  
   private function _int32($n) {
     while ( $n >= 2147483648 )
      $n -= 4294967296;
     while ( $n <= - 2147483649 )
      $n += 4294967296;
     return ( int ) $n;
  }
}

// 使用方式
$xxtea = new XxTea();
$ string = 'hello leven';
$key = '123456';
$encode = $xxtea->encrypt($ string,$key, true);
$decode = $xxtea->decrypt($encode,$key, true);
echo $encode;
echo "<br />";
echo $decode;