一文帶你搞懂字符集編碼

軟件開發人員經常遇到 “中文亂碼”、“軟件不能顯示日文” 等類似問題。真相只有一個——對字符集編碼沒有一個系統的認知。

常見字符集編碼有 GB2312、GBK、BIG5、UTF-8、UTF-16,甚至有些從事 MFC 開發的人可能還會說字符集有 ANSI 和 UNICODE。真的是這樣嗎?直接上乾貨。

字符集分類

1. ANSI

American National Standards Institute 美國國家標準學會,由這個標準學會制訂的一種編碼規則。

1.1. ASCII 編碼

ASCII 編碼即美國信息交換標準代碼(American Standard Code for Information Interchange)是一套共有 128 個字符的編碼,它基於阿拉丁字母,主要作用是用來表示英語和西歐語言字符。ASCII 規範編碼第一次公佈於 1967 年,ascii 碼在 1986 年完成最後一次更新。ASCII 碼對照表等同於國際標準 ISO/IEC 646,ASCII 碼對照表是世界最通用的信息交換標準。

ASCII 編碼

1.2. GB2312 編碼

GB2312 簡體中文編碼,一個漢字佔用 2 個字節,在大陸是主要的編碼方式,兼容 ASCII 編碼。

爲了支持繁體字,於是推出了 GBK 編碼,GBK 是國標擴展(Guo Biao Kuozhan)編碼的縮寫,兼容 GB2312。

爲了支持少數名民族的文字,於是推出了 GB1803,解決了中文、日文、朝鮮語等的編碼,兼容 GBK。

中文編碼

2. UNICODE 編碼

Unicode 又稱爲統一碼、萬國碼、單一碼,是國際組織制定的旨在容納全球所有字符的編碼方案,包括字符集、編碼方案等,它爲每種語言中的每個字符設定了統一且唯一的二進制編碼,以滿足跨語言、跨平臺的要求。

Unicode 字符集被劃分爲 17 個平面 (即,17 個區,編號爲 0-16),且具有以下特點:

Unicode 17 層平面

2.1. UTF-16 編碼

UTF-16 編碼源於 UCS-2,是 Unicode 最早的編碼方式。

因此,若軟件僅支持 UCS-2 編碼,則意味着僅支持 UCS 字符集或 Unicode 字符集基本平面中的字符,而不支持增補平面中的字符。

UTF-16 編碼後的碼元序列在映射爲物理意義上的字節序列時,又分爲 UTF-16BE (大端序),UTF-16LE (小端序)兩種情況,大端序和小端序又分爲帶有字節序標記 (with BOM) 和不帶字節序標記 (without BOM) 兩種情形。比如,“ABC”這三個字符的 UTF-16 編碼 (碼元序列) 爲:00 41 00 42 00 43;其對應的各種字節序列如下表所示:

”abc” 的各種 UTF-16 編碼

2.2. UTF-32 編碼

UTF-32 是一種將 Unicode 字符編碼的協定,對每一個 Unicode 碼位使用恰好 32 位元。其它的 Unicode transformation formats 則使用不定長度編碼。因爲 UTF-32 對每個字符都使用 4 字節,就空間而言,是非常沒有效率的。特別地,非基本多文種平面的字符在大部分文件中通常很罕見,以致於它們通常被認爲不存在佔用空間大小的討論,使得 UTF-32 通常會是其它編碼的二到四倍。雖然每一個碼位使用固定長定的字節看似方便,它並不如其它 Unicode 編碼使用得廣泛。

與 UTF-16 一樣,也存在大端和小端存儲。

2.3. UTF-8 編碼

UTF-8 編碼是 Unicode 編碼的一種編碼形式。由 1-6 個字節表示一個字符,兼容 ASCII 編碼。

UTF-8 編碼

3. MFC 中的字符集

MFC 字符集選擇多字節編碼時,對應的編碼是 GBK 編碼

MFC 字符集選擇 Unicode 編碼時,對應的編碼是 UTF-16 編碼。

4. QT 中的字符集

QString 是按 UTF-16 存儲的。

1、當選擇 UTF-8 編碼時,QString 構造函數的參數對應 UTF-8 編碼(默認設置)。

QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QString str = “右邊是UFT-8編碼的字符串”;

2、當選擇 GBK 編碼時,QString 構造函數的參數對應 GBK 編碼。

QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QString str = “右邊是GBK編碼的字符串”;

3、QString 也可以指定編碼賦值。

QString str1 = QString::fromLocal8Bit(“GBK編碼字符串”);
QString str2 = QString::fromUtf8(“UTF-8編碼字符串”);

作者: 你的程序猿大叔

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/OWk0HsRKb3LrfZo_De7OjA