MIME 兩種編碼方式
- Base64(標記 B/b):將 3 位元組轉為 4 個可列印字元,每字元實際用 6 bits,解決 7-bit 傳輸限制。適用於二進位與多語言文字。
- Quoted-Printable/QP(標記 Q/q):將非 ASCII 字元以
=XX 形式表示(XX 為十六進位),適合以 ASCII 為主的文字。
主旨編碼範例
Subject: =?gb2312?B?xOO6w6Oh?=
gb2312:字元集
B:Base64 編碼
xOO6w6Oh:編碼後資料(解碼後為「你好!」)
PHP 內建解碼函數
base64_decode($str)
quoted_printable_decode($str)
通用 decode_mime 函數
function decode_mime($string) {
$pos = strpos($string, '=?');
if (!is_int($pos)) return $string;
$preceding = substr($string, 0, $pos);
$search = substr($string, $pos + 2);
$d1 = strpos($search, '?');
if (!is_int($d1)) return $string;
$charset = substr($search, 0, $d1);
$search = substr($search, $d1 + 1);
$d2 = strpos($search, '?');
if (!is_int($d2)) return $string;
$encoding = substr($search, 0, $d2);
$search = substr($search, $d2 + 1);
$end = strpos($search, '?=');
if (!is_int($end)) return $string;
$encoded_text = substr($search, 0, $end);
$rest = substr($string, strlen($preceding . $charset . $encoding . $encoded_text) + 6);
switch (strtoupper($encoding)) {
case 'Q':
$decoded = quoted_printable_decode($encoded_text);
if (strtolower($charset) == 'windows-1251') {
$decoded = convert_cyr_string($decoded, 'w', 'k');
}
break;
case 'B':
$decoded = base64_decode($encoded_text);
if (strtolower($charset) == 'windows-1251') {
$decoded = convert_cyr_string($decoded, 'w', 'k');
}
break;
default:
$decoded = '=?' . $charset . '?' . $encoding . '?' . $encoded_text . '?=';
}
return $preceding . $decoded . $this->decode_mime($rest); // 遞迴處理多段編碼
}
說明
- 函數採遞迴方式處理同一字串中多段編碼。
- 支援
windows-1251 字元集自動轉換(可擴充其他)。
- 若格式不符預期,回傳原字串確保安全。