Discuz函数中最经典的函数是authcode函数,因为supesite,UCenterHome,UCenter,DiscuzX都使用了这个函数进行加密啊传输串与cookie
今天为大家带来authcode的详解,如果写的不好,请大家拍砖。喜欢的可以学习参考了!
1。/*
2。*
3。*函数作用:通过一个固定的密钥,对一个字符串进行加密解密,加密后的字符串是随机的
4。*参数解析:$string是被加密的字符串,$operation是操作类型('ENCODE'是加密,'DECODE'是解密操作),$key是加密时用的密钥,$expiry是过期时间
5。*使用举例:authcode('123','ENCODE','jordan',0);即用'jordan'这个字符串加密'123'这个字符串
6。*
7。**/
8。
9。functionauthcode($string,$operation='DECODE',$key='',$expiry=0){
10。
11。//keyc的长度,解密的时候需要用它与密钥生成密码本
12。$ckey_length=4;
13。
14。//对我们的密钥进行md5取值,32位固定值
15。$key=md5($key?$key:$GLOBALS['discuz_auth_key']);
16。
17。//keya是对上面的md5(密钥前16位)的再次md5
18。$keya=md5(substr($key,0,16));
19。
20。//keyb是对上面的md5(密钥后16位)的再次md5,验证串
21。$keyb=md5(substr($key,16,16));
22。
23。//取keyc的长度
24。//是解密,将keyc从密码串上截取下来注:keyc是传递过来的,不变
25。//是加密取md5(微秒串),并取下它的keyc长度个注:keyc是随机
26。$keyc=$ckey_length?($operation=='DECODE'?substr($string,0,$ckey_length):substr(md5(microtime()),-$ckey_length)):'';
27。
28。//用keya拼接上md5后的keya与keyc的拼接,用来加密或解密注:加密时随机,解密时固定
29。$cryptkey=$keya。md5($keya。$keyc);
30。
31。//$cryptkey长度是16+32=48
32。$key_length=strlen($cryptkey);
33。
34。//判断操作分为加密,解密,取得处理串
35。//如果是解密,截取下keyc的长度的串,因为加密的时候拼接在最前面了,并base64反解
36。//如果是加密,将时间戳拼接上过期秒数,格式化成十位的字符串,拼接上验证串的16位,再拼接原串
37。$string=$operation=='DECODE'?base64_decode(substr($string,$ckey_length)):sprintf('%010d',$expiry?$expiry+time():0)。substr(md5($string。$keyb),0,16)。$string;
38。
39。//取得处理串长度
40。$string_length=strlen($string);
41。
42。//初始化结果
43。$result='';
44。
45。//填充boxarray(0,1,2,3,。。。省略。。。,255);
46。$box=range(0,255);
47。
48。//打乱新密钥串,注解密时会生成相同的串
49。$rndkey=array();
50。for($i=0;$i<=255;$i++){
51。$rndkey[$i]=ord($cryptkey[$i%$key_length]);
52。}
53。
54。//继续打乱生成密码本
55。for($j=$i=0;$i<256;$i++){
56。$j=($j+$box[$i]+$rndkey[$i])%256;
57。$tmp=$box[$i];
58。$box[$i]=$box[$j];
59。$box[$j]=$tmp;
60。}
61。
62。//再次打乱生成密码本,保证机密随机
63。for($a=$j=$i=0;$i<$string_length;$i++){
64。$a=($a+1)%256;
65。$j=($j+$box[$a])%256;
66。$tmp=$box[$a];
67。$box[$a]=$box[$j];
68。$box[$j]=$tmp;
69。
70。//重点,字符串与密码本逐个进行抑或
71。$result。=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
72。}
73。
74。if($operation=='DECODE'){
75。//如果是解密
76。//验证是否过期,验证串是否与keyb所生成的串一致
77。if((substr($result,0,10)==0||substr($result,0,10)-time()>0)&&substr($result,10,16)==substr(md5(substr($result,26)。$keyb),0,16)){
78。//验证通过,返回原串
79。returnsubstr($result,26);
80。}else{
81。//否则返回空串
82。return'';
83。}
84。}else{
85。//如果是加密拼接keyc与base64(打乱串)
86。//加密完成
87。return$keyc。str_replace('=','',base64_encode($result));
88。}
89。
90。}