亂碼,是每個開發者都無法避開的「噩夢」。本質上,亂碼是「編碼與解碼方案不匹配」導致的數據誤讀。要從容應對亂碼,必須建立完整的字符編碼知識體系。本文為上篇,系統梳理 ASCII、擴展編碼、中文編碼家族、Unicode 標準及 UTF 族編碼實現原理;下篇將深入亂碼成因分類、逆向恢復實戰與工具鏈。
為兼容 ASCII,各國將最高位置 1 (128-255) 定義本國字符:
| 編碼 | 區域 | 字節長度 | 特點 |
|---|---|---|---|
| ISO-8859-1 (Latin-1) | 西歐 | 1 字節 | 0-255 直接映射,缺歐元符號 |
| Windows-1252 (CP1252) | 西歐 (Windows) | 1 字節 | 兼容 ISO-8859-1,128-159 补充印刷字符 (含 €),實際通用標準 |
| GB2312 | 中國大陸 (簡體) | 2 字節 | ~7000 漢字,高位字節 0xA1-0xF7,低位 0xA1-0xFE |
| GBK | 中國大陸 (簡繁兼容) | 2 字節 | 兼容 GB2312,~21000 字符,高位 0x81-0xFE,低位 0x40-0x7E/0x80-0xFE |
| GB18030 | 中國大陸 (國家標準) | 2/4 字節 | 兼容 GBK,~7萬字符含少數民族,雙字節同 GBK,四字節第二字節 0x30-0x39 識別 |
| Big5 | 台灣/香港 (繁體) | 2 字節 | ~1.3萬繁體字,高位 0x81-0xFE,低位 0x40-0x7E/0xA1-0xFE |
關鍵點:除 ASCII 兼容區 (0-127) 外,各編碼互不兼容。同一字節流用錯編碼解析,即產生亂碼。如法文 "Pékin" (Windows-1252: 50 E9 6B 69 6E) 用 GB18030 解讀變為 "P閗i"。
U+XXXX 格式,如「馬」= U+9A6C。將碼位轉為字節流的方案:
char / String 內部即 UTF-16,Windows API、JavaScript、Qt 等廣泛採用。編碼規則 (位模板):
| 碼位範圍 | 字節數 | 二進制模板 (x 為碼位位) | 覆蓋 |
|---|---|---|---|
| U+0000 ~ U+007F | 1 | 0xxxxxxx | ASCII (兼容!) |
| U+0080 ~ U+07FF | 2 | 110xxxxx 10xxxxxx | 拉丁、希臘、西里爾等 |
| U+0800 ~ U+FFFF | 3 | 1110xxxx 10xxxxxx 10xxxxxx | 中日韓統一表意文字 (CJK) |
| U+10000 ~ U+10FFFF | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | Emoji、罕用字 |
編碼算法: 碼位 → 二進制 (去除高位 0) → 從右向左填入模板 x 位 → 剩餘 x 補 0。
示例:「馬」 U+9A6C (39532) → UTF-8:
碼位二進制: 1001 101001 101100 (16位)
模板: 1110xxxx 10xxxxxx 10xxxxxx
填入: 11101001 10101001 10101100
十六進制: E9 A9 AC (3 字節)
任意編碼 A → 編碼 B = A 解碼 → Unicode 碼位 → B 編碼。
「馬」 轉換對照:
GB18030: C2 ED (2 字節)
Unicode: 9A 6C (碼位)
UTF-8: E9 A9 AC (3 字節)
UTF-16LE: 6C 9A (2 字節,小端)
轉換本質是查表/算法映射,**改變二進制位模式,保持字符語義不變**。
utf8mb4 (真正 4 字節 UTF-8,支援 Emoji),而非 utf8 (偽 UTF-8,僅 3 字節)。掌握從 ASCII 到 Unicode、UTF-8 編碼模板、中文編碼家族演進脈絡,是攻克亂碼問題的地基。下篇我們將實戰演示:如何從「鍋燉腿」逆向恢復「测试中文」,構建亂碼急救工具箱。