首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

字符編碼大全:ANSI、Unicode、GBK、UTF-8、UTF-16 區別與選型指南

     編輯:程式設計綜合問答

從 ASCII 到 Unicode:主流字符編碼的演進、原理與實戰選型

字符編碼是程序員繞不開的坑。本文梳理 ANSI、Unicode、GBK、UTF-8、UTF-16 的來龍去脈、存儲方式、適用場景。

核心概念速覽

編碼全稱覆蓋範圍碼元大小特點
ASCIIAmerican Standard Code for Information Interchange128 字符(英字母、數字、符號)1 字節基石,高位固定 0
ANSIAmerican National Standards Institute (誤稱)本地化代碼頁(如 CP936=GBK, CP1252=Western)1-2 字節非標準統稱,Windows 預設代碼頁
GBKGuoBiao KuoZhan中文簡體+繁體、日韓字符1-2 字節國標擴展,雙字節高位≥0x81,兼容 ASCII
UnicodeUniversal Character Set全球所有字符(149,186+ 字符,含 Emoji)抽象碼位字符集標準,不指定存儲方式
UTF-8Unicode Transformation Format - 8-bit全 Unicode1-4 字節變長,ASCII 兼容,網絡傳輸/文件存儲首選
UTF-16Unicode Transformation Format - 16-bit全 Unicode2 或 4 字節定長/代理對,Windows/Java/JS 內存內部表示
UTF-32Unicode Transformation Format - 32-bit全 Unicode4 字節定長,隨機訪問快,空間浪費大

關鍵區別:字符集 vs 編碼

  • 字符集:字符 → 數字碼位 的映射表。Unicode 是字符集。
  • 編碼:碼位 → 字節序列 的算法。UTF-8/UTF-16 是編碼。

「Unicode 編碼」是不嚴謬說法,應說「UTF-8 編碼的 Unicode 字符」。

變長編碼原理:UTF-8 位布局

碼位範圍          字節數  位模板
U+0000 ~ U+007F     1     0xxxxxxx                    (ASCII 兼容)
U+0080 ~ U+07FF     2     110xxxxx 10xxxxxx
U+0800 ~ U+FFFF     3     1110xxxx 10xxxxxx 10xxxxxx  (基本多文種平面 BMP)
U+10000 ~ U+10FFFF  4     11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (輔助平面,含 Emoji)

優勢:ASCII 文本無膨脹,中文 3 字節,Emoji 4 字節,自同步(無需從頭掃描即可找字符邊界)。

UTF-16 代理對

BMP 字符 (U+0000~U+FFFF)  → 直接存 2 字節
輔助平面 (U+10000+)     → 代理對:高代理 (D800-DBFF) + 低代理 (DC00-DFFF) = 4 字節
例:😂 U+1F602 → 0xD83D 0xDE02

實戰選型建議

  1. 文件存儲、網絡傳輸、HTML、JSON、數據庫:UTF-8(BOM 可選,建議無 BOM)。
  2. Windows API、Java String、JavaScript 字符串、Qt QString:內部用 UTF-16(引擎層透明處理)。
  3. 老舊中文系統維護:GBK/CP936(逐步遷移至 UTF-8)。
  4. 嵌入式極度受限:若僅需 ASCII + 少量字符,可考慮自定義編碼或 UTF-8 子集。

常見亂碼根因

現象原因修復
中文變「??」或方塊UTF-8 數據按 GBK 解碼統一指定 UTF-8
一個漢字變兩個亂碼GBK 數據按 UTF-8 解碼統一指定 GBK 或轉碼
Emoji 顯示為兩個UTF-16 代理對被當作兩字符使用支持代理對的字體/庫

編程語言轉碼速查

// Java
String utf8 = new String(gbkBytes, "GBK");  // 解碼
byte[] gbk = utf8Str.getBytes("GBK");       // 編碼

// Python 3
text = gbk_bytes.decode('gbk')
utf8_bytes = text.encode('utf-8')

// C++ (Windows API)
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, gbk, len, NULL, NULL);

徹底理解編碼本質,配合「統一內部用 Unicode(UTF-16/32),外部交互用 UTF-8」原則,可消滅 99% 亂碼問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved