TeaUtil.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: bingone
  5. * Date: 16/1/19
  6. * Time: 下午6:21
  7. */
  8. $date = '';
  9. $key = '002d88e24fdaf41801d1d18ef8109996';
  10. $t = new TeaUtil ();
  11. $tea = $t->encrypt($date, $key);
  12. $eetea = $t->decrypt($tea, $key);
  13. print $eetea;
  14. var_dump(base64_encode($tea));
  15. var_dump($eetea);
  16. class TeaUtil
  17. {
  18. public static function getBytes($string)
  19. {
  20. $bytes = array();
  21. for ($i = 0; $i < strlen($string); $i++) {
  22. $bytes[] = ord($string[$i]);
  23. }
  24. return $bytes;
  25. }
  26. private $a, $b, $c, $d;
  27. private $n_iter;
  28. public function __construct()
  29. {
  30. $this->setIter(32);
  31. }
  32. private function setIter($n_iter)
  33. {
  34. $this->n_iter = $n_iter;
  35. }
  36. private function getIter()
  37. {
  38. return $this->n_iter;
  39. }
  40. public function encrypt($data, $key)
  41. {
  42. // resize data to 32 bits (4 bytes)
  43. $n = $this->_resize($data, 8);
  44. // convert data to long
  45. $data_long [0] = $n;
  46. $n_data_long = $this->_str2long($n, $data, $data_long);
  47. // resize data_long to 64 bits (2 longs of 32 bits)
  48. $n = count($data_long);
  49. if (($n & 1) == 1) {
  50. $data_long [$n] = chr(0);
  51. $n_data_long++;
  52. }
  53. // resize key to a multiple of 128 bits (16 bytes)
  54. $this->_resize($key, 16, true);
  55. if ('' == $key)
  56. $key = '0000000000000000';
  57. // convert key to long
  58. $n_key_long = $this->_str2long(0, $key, $key_long);
  59. // encrypt the long data with the key
  60. $enc_data = '';
  61. $w = array(0, 0);
  62. $j = 0;
  63. $k = array(0, 0, 0, 0);
  64. for ($i = 0; $i < $n_data_long; ++$i) {
  65. // get next key part of 128 bits
  66. if ($j + 4 <= $n_key_long) {
  67. $k [0] = $key_long [$j];
  68. $k [1] = $key_long [$j + 1];
  69. $k [2] = $key_long [$j + 2];
  70. $k [3] = $key_long [$j + 3];
  71. } else {
  72. $k [0] = $key_long [$j % $n_key_long];
  73. $k [1] = $key_long [($j + 1) % $n_key_long];
  74. $k [2] = $key_long [($j + 2) % $n_key_long];
  75. $k [3] = $key_long [($j + 3) % $n_key_long];
  76. }
  77. $j = ($j + 4) % $n_key_long;
  78. $this->_encipherLong($data_long [$i], $data_long [++$i], $w, $k);
  79. // append the enciphered longs to the result
  80. $enc_data .= $this->_long2str($w [0]);
  81. $enc_data .= $this->_long2str($w [1]);
  82. }
  83. return $enc_data;
  84. }
  85. public function decrypt($enc_data, $key)
  86. {
  87. // convert data to long
  88. $n_enc_data_long = $this->_str2long(0, $enc_data, $enc_data_long);
  89. // resize key to a multiple of 128 bits (16 bytes)
  90. $this->_resize($key, 16, true);
  91. if ('' == $key)
  92. $key = '0000000000000000';
  93. // convert key to long
  94. $n_key_long = $this->_str2long(0, $key, $key_long);
  95. // decrypt the long data with the key
  96. $data = '';
  97. $w = array(0, 0);
  98. $j = 0;
  99. $len = 0;
  100. $k = array(0, 0, 0, 0);
  101. $pos = 0;
  102. for ($i = 0; $i < $n_enc_data_long; $i += 2) {
  103. // get next key part of 128 bits
  104. if ($j + 4 <= $n_key_long) {
  105. $k [0] = $key_long [$j];
  106. $k [1] = $key_long [$j + 1];
  107. $k [2] = $key_long [$j + 2];
  108. $k [3] = $key_long [$j + 3];
  109. } else {
  110. $k [0] = $key_long [$j % $n_key_long];
  111. $k [1] = $key_long [($j + 1) % $n_key_long];
  112. $k [2] = $key_long [($j + 2) % $n_key_long];
  113. $k [3] = $key_long [($j + 3) % $n_key_long];
  114. }
  115. $j = ($j + 4) % $n_key_long;
  116. $this->_decipherLong($enc_data_long [$i], $enc_data_long [$i + 1], $w, $k);
  117. // append the deciphered longs to the result data (remove padding)
  118. if (0 == $i) {
  119. $len = $w [0];
  120. if (4 <= $len) {
  121. $data .= $this->_long2str($w [1]);
  122. } else {
  123. $data .= substr($this->_long2str($w [1]), 0, $len % 4);
  124. }
  125. } else {
  126. $pos = ($i - 1) * 4;
  127. if ($pos + 4 <= $len) {
  128. $data .= $this->_long2str($w [0]);
  129. if ($pos + 8 <= $len) {
  130. $data .= $this->_long2str($w [1]);
  131. } elseif ($pos + 4 < $len) {
  132. $data .= substr($this->_long2str($w [1]), 0, $len % 4);
  133. }
  134. } else {
  135. $data .= substr($this->_long2str($w [0]), 0, $len % 4);
  136. }
  137. }
  138. }
  139. return $data;
  140. }
  141. private function _encipherLong($y, $z, &$w, &$k)
  142. {
  143. $sum = ( integer )0;
  144. $delta = 0x9E3779B9;
  145. $n = ( integer )$this->n_iter;
  146. while ($n-- > 0) {
  147. //C v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
  148. //C v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
  149. $sum = $this->_add($sum, $delta);
  150. $y = $this->_add($y, $this->_add(($z << 4), $this->a) ^ $this->_add($z, $sum) ^ $this->_add($this->_rshift($z, 5), $this->b));
  151. $z = $this->_add($z, $this->_add(($y << 4), $this->a) ^ $this->_add($y, $sum) ^ $this->_add($this->_rshift($y, 5), $this->b));
  152. }
  153. $w [0] = $y;
  154. $w [1] = $z;
  155. }
  156. private function _decipherLong($y, $z, &$w, &$k)
  157. {
  158. // sum = delta<<5, in general sum = delta * n
  159. $sum = 0xC6EF3720;
  160. $delta = 0x9E3779B9;
  161. $n = ( integer )$this->n_iter;
  162. while ($n-- > 0) {
  163. //C v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
  164. //C v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
  165. $z = $this->_add($z, -($this->_add(($y << 4), $this->a) ^ $this->_add($y, $sum) ^ $this->_add($this->_rshift($y, 5), $this->b)));
  166. $y = $this->_add($y, -($this->_add(($z << 4), $this->a) ^ $this->_add($z, $sum) ^ $this->_add($this->_rshift($z, 5), $this->b)));
  167. $sum = $this->_add($sum, -$delta);
  168. }
  169. $w [0] = $y;
  170. $w [1] = $z;
  171. }
  172. private function _resize(&$data, $size, $nonull = false)
  173. {
  174. $n = strlen($data);
  175. $nmod = $n % $size;
  176. if (0 == $nmod)
  177. $nmod = $size;
  178. if ($nmod > 0) {
  179. if ($nonull) {
  180. for ($i = $n; $i < $n - $nmod + $size; ++$i) {
  181. $data [$i] = $data [$i % $n];
  182. }
  183. } else {
  184. for ($i = $n; $i < $n - $nmod + $size; ++$i) {
  185. $data [$i] = chr(0);
  186. }
  187. }
  188. }
  189. return 8-$nmod;
  190. }
  191. private function _hex2bin($str)
  192. {
  193. $len = strlen($str);
  194. return pack('H' . $len, $str);
  195. }
  196. private function _str2long($start, &$data, &$data_long)
  197. {
  198. $n = strlen($data);
  199. $tmp = unpack('N*', $data);
  200. $j = $start;
  201. foreach ($tmp as $value)
  202. $data_long [$j++] = $value;
  203. return $j;
  204. }
  205. private function _long2str($l)
  206. {
  207. return pack('N', $l);
  208. }
  209. private function _rshift($integer, $n)
  210. {
  211. // convert to 32 bits
  212. if (0xffffffff < $integer || -0xffffffff > $integer) {
  213. $integer = fmod($integer, 0xffffffff + 1);
  214. }
  215. // convert to unsigned integer
  216. if (0x7fffffff < $integer) {
  217. $integer -= 0xffffffff + 1.0;
  218. } elseif (-0x80000000 > $integer) {
  219. $integer += 0xffffffff + 1.0;
  220. }
  221. // do right shift
  222. if (0 > $integer) {
  223. $integer &= 0x7fffffff; // remove sign bit before shift
  224. $integer >>= $n; // right shift
  225. $integer |= 1 << (31 - $n); // set shifted sign bit
  226. } else {
  227. $integer >>= $n; // use normal right shift
  228. }
  229. return $integer;
  230. }
  231. private function _add($i1, $i2)
  232. {
  233. $result = 0.0;
  234. foreach (func_get_args() as $value) {
  235. // remove sign if necessary
  236. if (0.0 > $value) {
  237. $value -= 1.0 + 0xffffffff;
  238. }
  239. $result += $value;
  240. }
  241. // convert to 32 bits
  242. if (0xffffffff < $result || -0xffffffff > $result) {
  243. $result = fmod($result, 0xffffffff + 1);
  244. }
  245. // convert to signed integer
  246. if (0x7fffffff < $result) {
  247. $result -= 0xffffffff + 1.0;
  248. } elseif (-0x80000000 > $result) {
  249. $result += 0xffffffff + 1.0;
  250. }
  251. return $result;
  252. }
  253. }
  254. ?>