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