算法简单,而且效率高,每次可以操作8个字节的数据,加密解密的KEY为16字节,即包含4个int数据的int型数组,加密轮数应为8的倍数,一般比较常用的轮数为64,32,16,QQ原来就是用TEA16来还原密码的.
    TEA算法  
  核心为:  
  #include<stdint.h>  
  voidencrypt(uint32_t*v,uint32_t*k){  
  uint32_tv0=v[0],v1=v[1],sum=0,i;/*setup*/  
  uint32_tdelta=0x9e3779b9;/*akeyscheduleconstant*/  
  uint32_tk0=k[0],k1=k[1],k2=k[2],k3=k[3];/*cachekey*/  
  for(i=0;i<32;i++){/*basiccyclestart*/  
  sum+=delta;  
  v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);  
  v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);  
  }/*endcycle*/  
  v[0]=v0;v[1]=v1;  
  }  
  voiddecrypt(uint32_t*v,uint32_t*k){  
  uint32_tv0=v[0],v1=v[1],sum=0xC6EF3720,i;/*setup*/  
  uint32_tdelta=0x9e3779b9;/*akeyscheduleconstant*/  
  uint32_tk0=k[0],k1=k[1],k2=k[2],k3=k[3];/*cachekey*/  
  for(i=0;i<32;i++){/*basiccyclestart*/  
  v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);  
  v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);  
  sum-=delta;  
  }/*endcycle*/  
  v[0]=v0;v[1]=v1;  
  }    
PHP部分代码非我原创
,大家可以了解一下这方面的知识  
  <?php  
  $date='8345354023476-3434';  
  $key='12345';  
  $t=newtea();  
  $tea=$t->encrypt($date,$key);  
  $eetea=$t->decrypt($tea,$key);  
  var_dump($tea);  
  var_dump($eetea);  
  classtea{  
  private$a,$b,$c,$d;  
  private$n_iter;  
  publicfunction__construct(){  
  $this->setIter(32);  
  }  
  privatefunctionsetIter($n_iter){  
  $this->n_iter=$n_iter;  
  }  
  privatefunctiongetIter(){  
  return$this->n_iter;  
  }  
  publicfunctionencrypt($data,$key){  
  //resizedatato32bits(4bytes)  
  $n=$this->_resize($data,4);  
  //convertdatatolong  
  $data_long[0]=$n;  
  $n_data_long=$this->_str2long(1,$data,$data_long);  
  //resizedata_longto64bits(2longsof32bits)  
  $n=count($data_long);  
  if(($n&1)==1){  
  $data_long[$n]=chr(0);  
  $n_data_long++;  
  }  
  //resizekeytoamultipleof128bits(16bytes)  
  $this->_resize($key,16,true);  
  if(''==$key)  
  $key='0000000000000000';  
  //convertkeytolong  
  $n_key_long=$this->_str2long(0,$key,$key_long);  
  //encryptthelongdatawiththekey  
  $enc_data='';  
  $w=array(0,0);  
  $j=0;  
  $k=array(0,0,0,0);  
  for($i=0;$i<$n_data_long;++$i){  
  //getnextkeypartof128bits  
  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);  
  //appendtheencipheredlongstotheresult  
  $enc_data.=$this->_long2str($w[0]);  
  $enc_data.=$this->_long2str($w[1]);  
  }  
  return$enc_data;  
  }  
  publicfunctiondecrypt($enc_data,$key){  
  //convertdatatolong  
  $n_enc_data_long=$this->_str2long(0,$enc_data,$enc_data_long);  
  //resizekeytoamultipleof128bits(16bytes)  
  $this->_resize($key,16,true);  
  if(''==$key)  
  $key='0000000000000000';  
  //convertkeytolong  
  $n_key_long=$this->_str2long(0,$key,$key_long);  
  //decryptthelongdatawiththekey  
  $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){  
  //getnextkeypartof128bits  
  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);  
  //appendthedecipheredlongstotheresultdata(removepadding)  
  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;  
  }  
  privatefunction_encipherLong($y,$z,&$w,&$k){  
  $sum=(integer)0;  
  $delta=0x9E3779B9;  
  $n=(integer)$this->n_iter;  
  while($n-->0){  
  //Cv0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);  
  //Cv1+=((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;  
  }  
  privatefunction_decipherLong($y,$z,&$w,&$k){  
  //sum=delta<<5,ingeneralsum=delta*n  
  $sum=0xC6EF3720;  
  $delta=0x9E3779B9;  
  $n=(integer)$this->n_iter;  
  while($n-->0){  
  //Cv1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);  
  //Cv0-=((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;  
  }  
  privatefunction_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;  
  }  
  privatefunction_hex2bin($str){  
  $len=strlen($str);  
  returnpack('H'.$len,$str);  
  }  
  privatefunction_str2long($start,&$data,&$data_long){  
  $n=strlen($data);  
  $tmp=unpack('N*',$data);  
  $j=$start;  
  foreach($tmpas$value)  
  $data_long[$j++]=$value;  
  return$j;  
  }  
  privatefunction_long2str($l){  
  returnpack('N',$l);  
  }  
  privatefunction_rshift($integer,$n){  
  //convertto32bits  
  if(0xffffffff<$integer||-0xffffffff>$integer){  
  $integer=fmod($integer,0xffffffff+1);  
  }  
  //converttounsignedinteger  
  if(0x7fffffff<$integer){  
  $integer-=0xffffffff+1.0;  
  }elseif(-0x80000000>$integer){  
  $integer+=0xffffffff+1.0;  
  }  
  //dorightshift  
  if(0>$integer){  
  $integer&=0x7fffffff;//removesignbitbeforeshift  
  $integer>>=$n;//rightshift  
  $integer|=1<<(31-$n);//setshiftedsignbit  
  }else{  
  $integer>>=$n;//usenormalrightshift  
  }  
  return$integer;  
  }  
  privatefunction_add($i1,$i2){  
  $result=0.0;  
  foreach(func_get_args()as$value){  
  //removesignifnecessary  
  if(0.0>$value){  
  $value-=1.0+0xffffffff;  
  }  
  $result+=$value;  
  }  
  //convertto32bits  
  if(0xffffffff<$result||-0xffffffff>$result){  
  $result=fmod($result,0xffffffff+1);  
  }  
  //converttosignedinteger  
  if(0x7fffffff<$result){  
  $result-=0xffffffff+1.0;  
  }elseif(-0x80000000>$result){  
  $result+=0xffffffff+1.0;  
  }  
  return$result;  
  }  
  //}}}  
  }  
  ?>  
  上面的是TEA的算法
,XTEA的算法为:  
  那
PHP中只需要把运算的位置改下就OK  
  privatefunction_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;  
  }  
  privatefunction_decipherLong($y,$z,&$w,&$k){  
  //sum=delta<<5,ingeneralsum=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的算法  
  核心为  
  #defineMX(z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(k[p&3^e]^z);  
  longbtea(long*v,longn,long*k){  
  unsignedlongz=v[n-1],y=v[0],sum=0,e,DELTA=0x9e3779b9;  
  longp,q;  
  if(n>1){/*CodingPart*/  
  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;  
  }  
  return0;  
  }elseif(n<-1){/*DecodingPart*/  
  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;  
  }  
  return0;  
  }  
  return1;  
  }  
  也是运算不一样,这个就不写了,有人已经写过这方面的代码了  
  #include<stdint.h>  
  voidencipher(unsignedintnum_rounds,uint32_tv[2],uint32_tconstk[4]){  
  unsignedinti;  
  uint32_tv0=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;  
  }  
  voiddecipher(unsignedintnum_rounds,uint32_tv[2],uint32_tconstk[4]){  
  unsignedinti;  
  uint32_tv0=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;  
  }