## PHP教程：TEA算法实现

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;
}
\$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;
}

// }}}
}
?>

#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 &#8722;= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum &#8722;= delta;
v0 &#8722;= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
v[0]=v0; v[1]=v1;
}

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;
}

CSS高级技巧:网页布局

Mootools 1.2教程 类(一)
ASP.NET页面借助IFrame提交表单数据所遇到问题的解决方法分享

jquery 简单图片导航插件jquery.imgNav.js
xhtml的标签和元素介绍

MySQL查询优化--数据类型与效率

js里的prototype使用示例