| 
 算法简单,而且效率高,每次可以操作8个字节的数据,加密解密的KEY为16字节,即包含4个int数据的int型数组,加密轮数应为8的倍数,一般比较常用的轮数为64,32,16,QQ原来就是用TEA16来还原密码的. 
TEA算法 核心为: 
 
#include <stdint.h> 
void encrypt (uint32_t* v, uint32_t* k) {     uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */     uint32_t delta=0x9e3779b9;                     /* a key schedule constant */     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */     for (i=0; i < 32; i++) {                       /* basic cycle start */         sum += delta;         v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);         v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);       }                                              /* end cycle */     v[0]=v0; v[1]=v1; } 
void decrypt (uint32_t* v, uint32_t* k) {     uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */     uint32_t delta=0x9e3779b9;                     /* a key schedule constant */     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */     for (i=0; i<32; i++) {                         /* basic cycle start */         v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);         v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);         sum -= delta;                                        }                                              /* end cycle */     v[0]=v0; v[1]=v1; } 
PHP部分代码非我原创,大家可以了解一下这方面的知识 
<?php $date = '8345354023476-3434'; $key = '12345'; $t = new tea ( ); $tea = $t->encrypt ( $date, $key ); $eetea = $t->decrypt ( $tea, $key ); var_dump ( $tea ); var_dump ( $eetea ); class tea {     private $a, $b, $c, $d;     private $n_iter;     public function __construct() {         $this->setIter ( 32 );     }     private function setIter($n_iter) {         $this->n_iter = $n_iter;     }     private function getIter() {         return $this->n_iter;     }     public function encrypt($data, $key) {         // resize data to 32 bits (4 bytes)         $n = $this->_resize ( $data, 4 );                  // convert data to long         $data_long [0] = $n;         $n_data_long = $this->_str2long ( 1, $data, $data_long );                  // resize data_long to 64 bits (2 longs of 32 bits)         $n = count ( $data_long );         if (($n & 1) == 1) {             $data_long [$n] = chr ( 0 );             $n_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 );                  // 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) {             // 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];             } else {                 $k [0] = $key_long [$j % $n_key_long];                 $k [1] = $key_long [($j + 1) % $n_key_long];                 $k [2] = $key_long [($j + 2) % $n_key_long];                 $k [3] = $key_long [($j + 3) % $n_key_long];             }             $j = ($j + 4) % $n_key_long;                          $this->_encipherLong ( $data_long [$i], $data_long [++ $i], $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];             } else {                 $k [0] = $key_long [$j % $n_key_long];                 $k [1] = $key_long [($j + 1) % $n_key_long];                 $k [2] = $key_long [($j + 2) % $n_key_long];                 $k [3] = $key_long [($j + 3) % $n_key_long];             }             $j = ($j + 4) % $n_key_long;                          $this->_decipherLong ( $enc_data_long [$i], $enc_data_long [$i + 1], $w, $k );                          // append the deciphered longs to the result data (remove padding)             if (0 == $i) {                 $len = $w [0];                 if (4 <= $len) {                     $data .= $this->_long2str ( $w [1] );                 } else {                     $data .= substr ( $this->_long2str ( $w [1] ), 0, $len % 4 );                 }             } else {                 $pos = ($i - 1) * 4;                 if ($pos + 4 <= $len) {                     $data .= $this->_long2str ( $w [0] );                                          if ($pos + 8 <= $len) {                         $data .= $this->_long2str ( $w [1] );                     } elseif ($pos + 4 < $len) {                         $data .= substr ( $this->_long2str ( $w [1] ), 0, $len % 4 );                     }                 } else {                     $data .= substr ( $this->_long2str ( $w [0] ), 0, $len % 4 );                 }             }         }         return $data;     }     private function _encipherLong($y, $z, &$w, &$k) {         $sum = ( integer ) 0;         $delta = 0x9E3779B9;         $n = ( integer ) $this->n_iter;                  while ( $n -- > 0 ) {                        //C v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);                        //C v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);               $sum = $this->_add ( $sum, $delta );             $y = $this->_add ( $y, $this->_add ( ($z << 4),$this->a) ^ $this->_add($z , $sum) ^ $this->_add($this->_rshift ( $z, 5 ), $this->b )  );             $z = $this->_add ( $z, $this->_add ( ($y << 4),$this->a) ^ $this->_add($y , $sum) ^ $this->_add($this->_rshift ( $y, 5 ), $this->b )  );         }                  $w [0] = $y;         $w [1] = $z;     }     private function _decipherLong($y, $z, &$w, &$k) {         // sum = delta<<5, in general sum = delta * n         $sum = 0xC6EF3720;         $delta = 0x9E3779B9;         $n = ( integer ) $this->n_iter;                  while ( $n -- > 0 ) {                     //C v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);                     //C v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);             $z = $this->_add ( $z, -($this->_add ( ($y << 4),$this->a) ^ $this->_add($y , $sum) ^ $this->_add($this->_rshift ( $y, 5 ), $this->b ) ) );             $y = $this->_add ( $y, - ($this->_add ( ($z << 4),$this->a) ^ $this->_add($z , $sum) ^ $this->_add($this->_rshift ( $z, 5 ), $this->b ) ) );             $sum = $this->_add ( $sum, - $delta );             }                  $w [0] = $y;         $w [1] = $z;     }     private function _resize(&$data, $size, $nonull = false) {         $n = strlen ( $data );         $nmod = $n % $size;         if (0 == $nmod)             $nmod = $size;                  if ($nmod > 0) {             if ($nonull) {                 for($i = $n; $i < $n - $nmod + $size; ++ $i) {                     $data [$i] = $data [$i % $n];                 }             } else {                 for($i = $n; $i < $n - $nmod + $size; ++ $i) {                     $data [$i] = chr ( 0 );                 }             }         }         return $n;     }     private function _hex2bin($str) {         $len = strlen ( $str );         return pack ( 'H' . $len, $str );     }     private function _str2long($start, &$data, &$data_long) {         $n = strlen ( $data );                  $tmp = unpack ( 'N*', $data );         $j = $start;                  foreach ( $tmp as $value )             $data_long [$j ++] = $value;                  return $j;     }     private function _long2str($l) {         return pack ( 'N', $l );     }               private function _rshift($integer, $n) {         // convert to 32 bits         if (0xffffffff < $integer || - 0xffffffff > $integer) {             $integer = fmod ( $integer, 0xffffffff + 1 );         }                  // convert to unsigned integer         if (0x7fffffff < $integer) {             $integer -= 0xffffffff + 1.0;         } elseif (- 0x80000000 > $integer) {             $integer += 0xffffffff + 1.0;         }                  // do right shift         if (0 > $integer) {             $integer &= 0x7fffffff; // remove sign bit before shift             $integer >>= $n; // right shift             $integer |= 1 << (31 - $n); // set shifted sign bit         } else {             $integer >>= $n; // use normal right shift         }                  return $integer;     }     private function _add($i1, $i2) {         $result = 0.0;                  foreach ( func_get_args () as $value ) {             // remove sign if necessary             if (0.0 > $value) {                 $value -= 1.0 + 0xffffffff;             }                          $result += $value;         }                  // convert to 32 bits         if (0xffffffff < $result || - 0xffffffff > $result) {             $result = fmod ( $result, 0xffffffff + 1 );         }                  // convert to signed integer         if (0x7fffffff < $result) {             $result -= 0xffffffff + 1.0;         } elseif (- 0x80000000 > $result) {             $result += 0xffffffff + 1.0;         }                  return $result;     }      // }}} } ?> 
上面的是TEA的算法,XTEA的算法为: 
 
#include <stdint.h> 
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[4]) {     unsigned int i;     uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;     for (i=0; i < num_rounds; i++) {         v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);         sum += delta;         v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);     }     v[0]=v0; v[1]=v1; } 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[4]) {     unsigned int i;     uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;     for (i=0; i < num_rounds; i++) {         v1 −= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);         sum −= delta;         v0 −= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);     }     v[0]=v0; v[1]=v1; } 
那PHP中只需要把运算的位置改下就OK 
    private function _teaencipherLong($y, $z, &$w, &$k) {         $sum = ( integer ) 0;         $delta = 0x9E3779B9;         $n = ( integer ) $this->n_iter;                  while ( $n -- > 0 ) {             $y = $this->_add ( $y, $this->_add ( $z << 4 ^ $this->_rshift ( $z, 5 ), $z ) ^ $this->_add ( $sum, $k [$sum & 3] ) );             $sum = $this->_add ( $sum, $delta );             $z = $this->_add ( $z, $this->_add ( $y << 4 ^ $this->_rshift ( $y, 5 ), $y ) ^ $this->_add ( $sum, $k [$this->_rshift ( $sum, 11 ) & 3] ) );         }                  $w [0] = $y;         $w [1] = $z;     }         private function _decipherLong($y, $z, &$w, &$k) {         // sum = delta<<5, in general sum = delta * n         $sum = 0xC6EF3720;         $delta = 0x9E3779B9;         $n = ( integer ) $this->n_iter;                  while ( $n -- > 0 ) {             $z = $this->_add ( $z, - ($this->_add ( $y << 4 ^ $this->_rshift ( $y, 5 ), $y ) ^ $this->_add ( $sum, $k [$this->_rshift ( $sum, 11 ) & 3] )) );             $sum = $this->_add ( $sum, - $delta );             $y = $this->_add ( $y, - ($this->_add ( $z << 4 ^ $this->_rshift ( $z, 5 ), $z ) ^ $this->_add ( $sum, $k [$sum & 3] )) );         }                  $w [0] = $y;         $w [1] = $z;     } 
XXTEA的算法 核心为 
 
#define MX (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z); 
  long btea(long* v, long n, long* k) {     unsigned long z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9;     long p, q ;     if (n > 1) {          /* Coding Part */       q = 6 + 52/n;       while (q-- > 0) {         sum += DELTA;         e = (sum >> 2) & 3;         for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX;         y = v[0];         z = v[n-1] += MX;       }       return 0 ;      } else if (n < -1) {  /* Decoding Part */       n = -n;       q = 6 + 52/n;       sum = q*DELTA ;       while (sum != 0) {         e = (sum >> 2) & 3;         for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;         z = v[n-1];         y = v[0] -= MX;         sum -= DELTA;       }       return 0;     }     return 1;   } 
也是运算不一样,这个就不写了,有人已经写过这方面的代码了 地址 
经典论坛交流: http://bbs.blueidea.com/thread-2928599-1-1.html 
本文链接:http://www.blueidea.com/tech/program/2009/6788.asp  
出处:蓝色理想
 
责任编辑:bluehearts 
◎进入论坛网络编程版块参加讨论
	       |