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