function authcode ($string, $operation, $key = '') {
#string 爲需加、解密字符串
#operation DECODE時解密
$key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
$key_length = strlen($key);
$string = $operation == 'DECODE' ? base64_decode($string) : substr(md5($string.$key), 0, 8).$string;
#注意這裏,如果不是解密的話。string爲string&key的md5的前8位。
$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;
#以上的過程就是加、解密的過程。雖說寫的很複雜,但是原理很簡單。只要key不變,($box[($box[$a] + $box[$j]) % 256])都是唯一的值,加密時當1^0時變成了1,解密時1^0自然變成了1,或者這樣說,加密時0^1變成1,解密時1^1就變成了0.
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
所以經過這個過程,是解密時,$result此時就被還原了.
}
if($operation == 'DECODE') {
echo substr($result, 0, 8).'<br>';
之前說 $string的前8位是key的md5的前8位,後面就是string,所以下面這個判斷也就不難理解了.
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));
}
}
轉載請注:來自http://hi.baidu.com/studyphp
後附:base64的編,解碼原理
Base64 編碼其實是將3個8位字節轉換爲4個6位字節,( 3*8 = 4*6 = 24 ) 這4個六位字節 其實仍然是8位,只不過高兩位被設置爲0. 當一個字節只有6位有效時,它的取值空間爲0 到 2的6次方減1 即63,也就是說被轉換的Base64編碼的每一個編碼的取值空間爲(0~63) 。
事實上,0~63之間的ASCII碼有許多不可見字符,所以應該再做一個映射,映射表爲
‘A‘ ~ ‘Z‘ ? ASCII(0 ~ 25)
‘a’ ~ ‘z‘ ? ASCII(26 ~ 51)
‘0’ ~ ‘9‘ ? ASCII(52 ~ 61)
‘+‘ ? ASCII(62)
‘/‘ ? ASCII(63)
這樣就可以將3個8位字節,轉換爲4個可見字符。
具體的字節拆分方法爲:(圖(畫得不好,領會精神 :-))
aaaaaabb ccccdddd eeffffff //abcdef其實就是1或0,爲了看的清楚就用abcdef代替
~~~~~~~~ ~~~~~~~~ ~~~~~~~~
字節 1 字節 2 字節 3
||
//
00aaaaaa 00bbcccc 00ddddee 00ffffff
注:上面的三個字節位原文,下面四個字節爲Base64編碼,其前兩位均爲0。
這樣拆分的時候,原文的字節數量應該是3的倍數,當這個條件不能滿足時,用全零字節
補足,轉化時Base64編碼用=號代替,這就是爲什麼有些Base64編碼以一個或兩個等號結
束的原因,但等號最多有兩個,因爲:如果F(origin)代表原文的字節數,F(remain)代
表餘數,則
F(remain) = F(origin) MOD 3 成立。
所以F(remain)的可能取值爲0,1,2.
如果設 n = [F(origin) – F(remain)] / 3
當F(remain) = 0 時,恰好轉換爲4*n個字節的Base64編碼。
當F(remain) = 1 時,由於一個原文字節可以拆分爲屬於兩個Base64編碼的字節,爲了
讓Base64編碼是4的倍數,所以應該爲補2個等號。
當F(remain) = 2 時,由於兩個原文字節可以拆分爲屬於3個Base64編碼的字節,同理,
應該補上一個等號。