discuz加密解密函数使用方法和中文注释


Posted in PHP onJanuary 21, 2014
<?php
/**
 * $string 明文或密文
 * $operation 加密ENCODE或解密DECODE
 * $key 密钥
 * $expiry 密钥有效期
 */ 
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
    // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
    // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
    // 当此值为 0 时,则不产生随机密钥
    $ckey_length = 4;    // 密匙
    // $GLOBALS['discuz_auth_key'] 这里可以根据自己的需要修改
    $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') {
        // substr($result, 0, 10) == 0 验证数据有效性
        // substr($result, 0, 10) - time() > 0 验证数据有效性
        // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
        // 验证数据有效性,请看未加密明文的格式
        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));
    }
}


$a = 3water.com;
$b = authcode($a, "ENCODE", "abc123");
echo $b."<br/>";
echo authcode($b, "DECODE", "abc123");
?>
PHP 相关文章推荐
杏林同学录(九)
Oct 09 PHP
php discuz 主题表和回帖表的设计
Mar 13 PHP
php 保留字列表
Oct 04 PHP
高性能PHP框架Symfony2经典入门教程
Jul 08 PHP
PHP 生成微信红包代码简单
Mar 25 PHP
XHProf报告字段含义的解析
May 17 PHP
php获取flash尺寸详细数据的方法
Nov 12 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
Dec 14 PHP
PHP批量删除jQuery操作
Jul 23 PHP
thinkPHP5实现的查询数据库并返回json数据实例
Oct 23 PHP
php解压缩zip和rar压缩包文件的方法
Jul 10 PHP
PHP程序员简单的开展服务治理架构操作详解(三)
May 14 PHP
php加密算法之实现可逆加密算法和解密分享
Jan 21 #PHP
检查用户名是否已在mysql中存在的php写法
Jan 20 #PHP
php设计模式之单例模式使用示例
Jan 20 #PHP
php实现图形显示Ip地址的代码及注释
Jan 20 #PHP
php判断手机访问还是电脑访问示例分享
Jan 20 #PHP
利用中国天气预报接口实现简单天气预报
Jan 20 #PHP
php日历制作代码分享
Jan 20 #PHP
You might like
PHP数据库调用类调用实例(详细注释)
2012/07/12 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
2014/10/23 PHP
php使用mysqli向数据库添加数据的方法
2015/03/20 PHP
Yii2框架数据验证操作实例详解
2018/05/02 PHP
ajaxControlToolkit AutoCompleteExtender的用法
2008/10/30 Javascript
Javascript 刷新全集常用代码
2009/11/22 Javascript
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
url参数中有+、空格、=、%、&amp;、#等特殊符号的问题解决
2013/05/15 Javascript
jQuery实现表头固定效果的实例代码
2013/05/24 Javascript
ES6的新特性概览
2016/03/10 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
基于JavaScript实现前端文件的断点续传
2016/10/17 Javascript
JS简单判断滚动条的滚动方向实现方法
2017/04/28 Javascript
Vue-cli创建项目从单页面到多页面的方法
2017/09/20 Javascript
基于jQuery Ajax实现下拉框无刷新联动
2017/12/06 jQuery
nodejs简单实现TCP服务器端和客户端的聊天功能示例
2018/01/04 NodeJs
微信小程序实现横向增长表格的方法
2018/07/24 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
2019/09/06 Javascript
Vuex中实现数据状态查询与更改
2019/11/08 Javascript
JS PHP字符串截取函数实现原理解析
2020/08/29 Javascript
[03:01]完美世界DOTA2联赛PWL S2 集锦第二期
2020/12/03 DOTA
Python中使用HTMLParser解析html实例
2015/02/08 Python
django 使用 request 获取浏览器发送的参数示例代码
2018/06/11 Python
对python中的高效迭代器函数详解
2018/10/18 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
2019/12/11 Python
深入浅析python变量加逗号,的含义
2020/02/22 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
CSS3 简写animation
2012/05/10 HTML / CSS
美国男士西装打折店:Jos. A. Bank
2017/11/13 全球购物
美体小铺印度官网:The Body Shop印度
2019/10/17 全球购物
求职信内容怎么写
2014/05/26 职场文书
医药销售自我评价200字
2014/09/11 职场文书
总经理岗位职责
2015/02/04 职场文书
2015年乡镇平安建设工作总结
2015/05/13 职场文书
大学毕业晚会开场白
2015/05/29 职场文书
进行数据处理的6个 Python 代码块分享
2022/04/06 Python