PHP教程:TEA算法完成-Php-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝29
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:201回复:0

  PHP教程:TEA算法完成

楼主#
更多 发布于:2016-05-19 16:16

:算法简略,而且效率高,每次能够操作8个字节的数据,加密解密的KEY为16字节,即包括4个int数据的int型数组,加密轮数应为8的倍数,通常对比常用的轮数为64,32,16,QQ本来即是用TEA16来复原暗码的.

算法简略,而且效率高,每次能够操作8个字节的数据,加密解密的KEY为16字节,即包括4个int数据的int型数组,加密轮数应为8的倍数,通常对比常用的轮数为64,32,16,QQ本来即是用TEA16来复原暗码的.

TEA算法

中心为:

#include

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)

v1="">>5) + k1);

v1 += ((v0<<4)

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)

v0="">>5) + k3);

v0 -= ((v1<<4)

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)

v1="">>5) + k1);

//C v1 += ((v0<<4)

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)

v0="">>5) + k3);

//C v0 -= ((v1<<4)

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

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;

}

也是运算不一样,这个就不写了,有人现已写过这方面的代码了

[font=Tahoma  ]

优质IT资源分享社区为你提供此文。

本站有大量优质php教程视频,资料等资源,包含php基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。

php教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客