方法一:
- /**
- * @param $string 要加密 / 解密的字符串
- * @param string $operation 类型, ENCODE 加密; DECODE 解密
- * @param string $key 密匙
- * @param int $expiry 有效期
- * @return string
- */
- function authcode($string, $operation = 'DECODE', $key = 'encrypt', $expiry = 0)
- {
- // 动态密匙长度, 相同的明文会生成不同密文就是依靠动态密匙
- $ckey_length = 4;
- // 密匙
- $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
- // 密匙 a 会参与加解密
- $keya = md5(substr($key, 0, 16));
- // 密匙 b 会用来做数据完整性验证
- $keyb = md5(substr($key, 16, 16));
- // 密匙 c 用于变化生成的密文
- $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) :
- substr(md5(microtime()), -$ckey_length)) : '';
- // 参与运算的密匙
- $cryptkey = $keya . md5($keya . $keyc);
- $key_length = strlen($cryptkey);
- // 明文, 前 10 位用来保存时间戳, 解密时验证数据有效性, 10 到 26 位用来保存 $keyb(密匙 b),
- // 解密时会通过这个密匙验证数据完整性
- // 如果是解码的话, 会从第 $ckey_length 位开始, 因为密文前 $ckey_length 位保存 动态密匙, 以保证解密正确
- $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) :
- sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
- $string_length = strlen($string);
- $result = '';
- $box = range(0, 255);
- $rndkey = array();
- // 产生密匙簿
- for ($i = 0; $i <= 255; $i++) {
- $rndkey[$i] = ord($cryptkey[$i % $key_length]);
- }
- // 用固定的算法, 打乱密匙簿, 增加随机性, 好像很复杂, 实际上对并不会增加密文的强度
- for ($j = $i = 0; $i <256; $i++) {
- $j = ($j + $box[$i] + $rndkey[$i]) % 256;
- $tmp = $box[$i];
- $box[$i] = $box[$j];
- $box[$j] = $tmp;
- }
- // 核心加解密部分
- for ($a = $j = $i = 0; $i < $string_length; $i++) {
- $a = ($a + 1) % 256;
- $j = ($j + $box[$a]) % 256;
- $tmp = $box[$a];
- $box[$a] = $box[$j];
- $box[$j] = $tmp;
- // 从密匙簿得出密匙进行异或, 再转成字符
- $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
- }
- if ($operation == 'DECODE') {
- // 验证数据有效性, 请看未加密明文的格式
- if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time()> 0) &&
- substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)
- ) {
- return substr($result, 26);
- } else {
- return '';
- }
- } else {
- // 把动态密匙保存在密文里, 这也是为什么同样的明文, 生产不同密文后能解密的原因
- // 因为加密后的密文可能是一些特殊字符, 复制过程可能会丢失, 所以用 base64 编码
- return $keyc . str_replace('=', '', base64_encode($result));
- }
- }
使用:
- $string = '加密字符串';
- // 加密
- $encode = authcode($string, 'ENCODE');
- echo $encode . '</br>'; // a2f4bSYyUrTum1nAAA9X9BrC4Z3DZazcSa4eLcvDoCnmYc1LTdvtqS4aCds
- // 解密
- $decode = authcode($encode, 'DECODE');
- echo $decode; // 加密字符串
方法二:
- /**
- * @param $string 要加密 / 解密的字符串
- * @param $operation 类型, E 加密; D 解密
- * @param string $key 密钥
- * @return mixed|string
- */
- function encrypt($string, $operation, $key = 'encrypt')
- {
- $key = md5($key);
- $key_length = strlen($key);
- $string = $operation == 'D' ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string;
- $string_length = strlen($string);
- $rndkey = $box = array();
- $result = '';
- for ($i = 0; $i <= 255; $i++) {
- $rndkey[$i] = ord($key[$i % $key_length]);
- $box[$i] = $i;
- }
- for ($j = $i = 0; $i <256; $i++) {
- $j = ($j + $box[$i] + $rndkey[$i]) % 256;
- $tmp = $box[$i];
- $box[$i] = $box[$j];
- $box[$j] = $tmp;
- }
- for ($a = $j = $i = 0; $i < $string_length; $i++) {
- $a = ($a + 1) % 256;
- $j = ($j + $box[$a]) % 256;
- $tmp = $box[$a];
- $box[$a] = $box[$j];
- $box[$j] = $tmp;
- $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
- }
- if ($operation == 'D') {
- if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
- return substr($result, 8);
- } else {
- return '';
- }
- } else {
- return str_replace('=', '', base64_encode($result));
- }
- }
使用:
- $string = '加密字符串';
- // 加密
- $encode = encrypt($string, 'E');
- echo $encode . '</br>'; // 0Jzym5UzkRKH726U7Pyt7ixzLz9YEEA
- // 解密
- $decode = encrypt($encode, 'D');
- echo $decode; // 加密字符串
方法三:
- /**
- * @param $data 要加密的字符串
- * @param $key 密钥
- * @return string
- */
- function encrypt($data, $key = 'encrypt')
- {
- $key = md5($key);
- $x = 0;
- $len = strlen($data);
- $l = strlen($key);
- $char = '';
- for ($i = 0; $i <$len; $i++) {
- if ($x == $l) {
- $x = 0;
- }
- $char .= $key{$x};
- $x++;
- }
- $str = '';
- for ($i = 0; $i < $len; $i++) {
- $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
- }
- return base64_encode($str);
- }
- /**
- * @param $data 要解密的字符串
- * @param $key 密钥
- * @return string
- */
- function decrypt($data, $key = 'encrypt')
- {
- $key = md5($key);
- $x = 0;
- $data = base64_decode($data);
- $len = strlen($data);
- $l = strlen($key);
- $char = '';
- for ($i = 0; $i < $len; $i++) {
- if ($x == $l) {
- $x = 0;
- }
- $char .= substr($key, $x, 1);
- $x++;
- }
- $str = '';
- for ($i = 0; $i < $len; $i++) {
- if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
- $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
- } else {
- $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
- }
- }
- return $str;
- }
使用:
- $string = '加密字符串';
- // 加密
- $encode = encrypt($string);
- echo $encode . '</br>'; // Gr0DHeHrRw7KGBLcSOzj
- // 解密
- $decode = decrypt($encode);
- echo $decode; // 加密字符串
来源: http://www.bubuko.com/infodetail-2803228.html