php tea加密,PHP之TEA算法实现

本文介绍了TEA(Tiny Encryption Algorithm)和XTEA加密算法,并提供了PHP的实现代码。TEA算法简单高效,使用16字节密钥,而XTEA是对TEA的改进,提高了安全性。PHP代码中展示了加密和解密过程,适用于理解这些算法的工作原理。
摘要由CSDN通过智能技术生成

算法简单,而且效率高,每次可以操作8个字节的数据,加密解密的KEY为16字节,即包含4个int数据的int型数组,加密轮数应为8的倍数,一般比较常用的轮数为64,32,16,QQ原来就是用TEA16来还原密码的.

#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) + 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部分代码非我原创,大家可以了解一下这方面的知识

$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

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;

}

#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

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;

}

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

地址

◎进入论坛网络编程版块参加讨论

Tea语言又称(Tealang)是一种新的计算机编程语言,采用强规范设计(规范即语法),拥有简约的强类型系统和单元模块体系,支持类型推断,支持面向对象和函数式编程,语法精炼简洁。其目标是成为一个友好的,支持多端开发的编程语言,并尽量支持常用编程语言生态,让开发者可以继续使用已有工作成果。目前通过编译生成PHP代码运行,可调用PHP库,可用于Web服务器端开发。预计后续将支持部分其它编程语言。 Tea语言非常注重语法的友好性,通过对语法进行优化设计,希望开发者可以更轻松自然的编写代码,可以更专注于创意实现。也尽量保持了常用编程语言的语法风格和习惯,以降低学习成本。 Tea语言项目最早开始于19年2月份,项目初衷主要是用于提升内部开发效率和实现产品功能,最初特性较少,在完善和优化后,于19年12月初首次发布开源。 Tea语言特性: 强规范,规范即语法,简洁清晰 简约的,带类型推断的强类型系统,编译时将进行类型推断与检查 便捷的XView类型,非常适合用于Web视图组件开发 智能的Return Collector特性,可自动按类型捕获数据到数组作为返回值 有限的类型兼容性,数据操作便捷而不失安全性 内置类型被封装成伪对象,支持对象成员风格调用,如:"Some string".length 内置单元模块(Unit)体系,基于单元模块组织程序,和访问控制 无普通全局变量,变量作用域最高为普通函数层级,无需担心全局变量污染问题 字符串处理语法灵活、简单而强大 流程控制语法灵活、简约、统一(所有都支持catch/finally分支,for支持else分支) 运算符规则简单有规律,易于记忆 支持Lambda表达式和普通函数,函数是一等公民 支持类和接口,接口可带默认实现,面向对象特性简单而不失强大 支持普通函数、普通常量、类和接口的访问控制(public/internal) 支持类/接口成员的访问控制(public/internal/protected/private) 通过编译生成目标语言代码的方式运行 Tea语言安装和使用: 安装PHP 7.2+,编译器和编译输出的程序依赖PHP 7.2或以上版本运行环境 安装好PHP后,将PHP执行文件所在目录添加到操作系统环境变量 将Tea语言项目克隆到本地(或其它方式下载,但需保证Tea语言项目的目录名称为tea)  # clone with the Git client  git clone https://github.com/tealang/tea.git 将当前目录切换到tea的上级目录中,执行如下命令即可编译示例程序:  # use the normal method  php tea/bin/tea tea/examples 如使用Mac或Linux系统,可使用Shebang方式,如:  # lets the scripts could be execute  chmod +x tea/bin/*  # use the Shebang method  tea/bin/tea tea/docs 在编译目标Unit的dist目录中可看到编译结果 创建或初始化一个新的Unit,如:  php tea/bin/tea --init myproject/hello
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值