標準 Base64 輸出包含 +/= 需 URL 編碼,且長度固定為 4 的倍數。Encode64 使用 64 個 URL 安全字符(A-Za-z0-9-_),無填充字符,編碼後字符串可直接用於 URL 路徑、Query 參數、Cookie 值,無需額外 urlencode。
const KEY = 'PaAwO65goUf7IK2vi9-xq8cFTEXLCDY1Hd3tV0ryzjbpN_BlnSs4mGRkQWMZJeuh';
共 64 字符,順序經過打亂,增加可讀性混淆度。
<?php
declare(strict_types=1);
class Encode64 {
private const KEY = 'PaAwO65goUf7IK2vi9-xq8cFTEXLCDY1Hd3tV0ryzjbpN_BlnSs4mGRkQWMZJeuh';
private const MASK = 0x3f; // 6 bits
public static function encode(string $str): string {
$bytes = self::strToBytes($str);
$len = count($bytes);
$res = $len % 3;
$out = '';
for ($i = 2; $i < $len; $i += 3) {
$v = $bytes[$i-2] | ($bytes[$i-1] << 8) | ($bytes[$i] << 16);
$out .= self::KEY[$v & self::MASK];
$out .= self::KEY[($v >> 6) & self::MASK];
$out .= self::KEY[($v >> 12) & self::MASK];
$out .= self::KEY[($v >> 18) & self::MASK];
}
if ($res === 1) {
$v = $bytes[$len-1];
$out .= self::KEY[$v & self::MASK];
$out .= self::KEY[($v >> 6) & self::MASK];
} elseif ($res === 2) {
$v = $bytes[$len-2] | ($bytes[$len-1] << 8);
$out .= self::KEY[$v & self::MASK];
$out .= self::KEY[($v >> 6) & self::MASK];
$out .= self::KEY[($v >> 12) & self::MASK];
}
return $out;
}
public static function decode(string $code): string {
$dic = array_flip(str_split(self::KEY));
$len = strlen($code);
$res = $len % 4;
$byteLen = (int)($len / 4) * 3;
if ($res === 2) $byteLen += 1;
elseif ($res === 3) $byteLen += 2;
$bytes = [];
for ($i = 3; $i < $len; $i += 4) {
$v = $dic[$code[$i-3]]
| ($dic[$code[$i-2]] << 6)
| ($dic[$code[$i-1]] << 12)
| ($dic[$code[$i]] << 18);
$bytes[] = $v & 0xff;
$bytes[] = ($v >> 8) & 0xff;
$bytes[] = ($v >> 16) & 0xff;
}
if ($res === 2) {
$v = $dic[$code[$len-2]] | ($dic[$code[$len-1]] << 6);
$bytes[] = $v & 0xff;
} elseif ($res === 3) {
$v = $dic[$code[$len-3]] | ($dic[$code[$len-2]] << 6) | ($dic[$code[$len-1]] << 12);
$bytes[] = $v & 0xff;
$bytes[] = ($v >> 8) & 0xff;
}
return self::bytesToStr($bytes);
}
private static function strToBytes(string $str): array {
$utf16 = iconv('UTF-8', 'UTF-16BE', $str);
return array_map('ord', str_split($utf16));
}
private static function bytesToStr(array $bytes): string {
return iconv('UTF-16BE', 'UTF-8', implode(array_map('chr', $bytes)));
}
}
// 測試
$original = 'Hello 中文 🚀';
$encoded = Encode64::encode($original);
$decoded = Encode64::decode($encoded);
echo "Original: $original\n";
echo "Encoded: $encoded\n";
echo "Decoded: $decoded\n";
echo "Match: " . ($original === $decoded ? 'YES' : 'NO') . "\n";
/* 輸出示例
Original: Hello 中文 🚀
Encoded: 9k2m8pQ3wsx1
Decoded: Hello 中文 🚀
Match: YES
*/
| 特性 | Base64 | Encode64 |
|---|---|---|
| 字符集 | A-Za-z0-9+/= | A-Za-z0-9-_ (無 =) |
| URL 安全 | 需 urlencode | 原生安全 |
| 長度開銷 | ~33% + 填充 | ~33% 無填充 |
| 可逆性 | 是 | 是 |
| PHP 內建 | base64_encode/decode | 需自帶類 |