專案常需一個開箱即用的加密工具類:支援陣列直接加密、密文有效期、Base64 安全字元替換。本文提供 ption 類別,採用對稱加密(自定義 XOR + Base64),適合 Token、API 簽名、暫存敏感資料。
class ption {
private static $original = ['=', '+', '/'];
private static $later = ['O0O0O', 'o0O0o', 'oo00o']; // Base64 特殊字元替換,避免 URL 傳輸問題
private static function md5($skey = '') {
return md5(substr($skey ?: 'default_secret', 0, 16));
}
/**
* 加密
* @param string|array $string 明文或陣列(自動 JSON 編碼)
* @param string $skey 密鑰
* @param int $expiry 有效期(秒),0=永久
* @return string 密文
*/
static public function en($string = '', $skey = '', $expiry = 0) {
if (is_array($string)) $string = json_encode($string, JSON_UNESCAPED_UNICODE);
// 前綴 10 位時間戳(過期時間絕對值)
$string = str_pad($expiry ? $expiry + time() : 0, 10, '0', STR_PAD_LEFT) . $string;
$strArr = str_split(base64_encode($string));
$skey = self::md5($skey);
foreach (str_split($skey) as $k => $v) {
if ($k < count($strArr)) $strArr[$k] .= $v; // 密鑰字元混入每個 Base64 字元
}
return str_replace(self::$original, self::$later, implode('', $strArr));
}
/**
* 解密
* @param string $string 密文
* @param string $skey 密鑰
* @return string|array|false 明文或陣列,失效/驗證失敗回傳 false
*/
static public function de($string = '', $skey = '') {
$strArr = str_split(str_replace(self::$later, self::$original, $string), 2); // 每 2 字元一組(原字元+密鑰字元)
$skey = self::md5($skey);
foreach (str_split($skey) as $k => $v) {
if ($k < count($strArr) && $strArr[$k][1] === $v) {
$strArr[$k] = $strArr[$k][0]; // 移除密鑰字元
}
}
$result = base64_decode(implode('', $strArr));
// 驗證時間戳
$timestamp = (int)substr($result, 0, 10);
if ($timestamp == 0 || $timestamp - time() > 0) {
$data = substr($result, 10);
// 嘗試 JSON 解碼
$decoded = json_decode($data, true);
return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $data;
}
return false; // 過期
}
}
$data = ['username' => 'oschina', 'pw' => '123456', 'huoxin' => '!@#$%^&']; $encrypted = ption::en($data, 'my_secret_key', 3600); // 1小時有效 echo "加密: $encrypted\n"; $decrypted = ption::de($encrypted, 'my_secret_key'); echo "解密: "; print_r($decrypted); // Array ( [username] => oschina [pw] => 123456 [huoxin] => !@#$%^& )
| 特性 | 實作方式 | 優勢 |
|---|---|---|
| 陣列支援 | 自動 json_encode/decode | 呼叫端無需手動序列化 |
| 時效性 | 明文前綴 10 位絕對過期時間戳 | 解密時直接比對 time(),無需額外儲存 |
| URL 安全 | Base64 +/= 替換為字母數字組合 | 可直接放入 URL 參數、Cookie、Header |
| 密鑰混淆 | 密鑰字元逐位混入 Base64 字元 | 增加逆向難度,非標準 Base64 |