本文作者在使用 VS2019 調試 python 程序過程中,終端打印中文出現亂碼。嘗試從網絡上收集解釋,發現對亂碼問題缺乏系統闡述,且每個解決均缺乏相關背景概念,不利於遇到同樣問題的用戶排查問題。因此本來的小隨筆轉換成了系列文章。
該系列主要四個部分組成:
➡️ VS2019 visual studio 終端亂碼01 - 相關基礎概念
VS2019 visual studio 終端亂碼02 - 查看修改終端編碼
VS2019 visual studio 終端亂碼03 - VS中查看修改文件編碼
VS2019 visual studio 終端亂碼04 - 亂碼案例
本節目標
- 明確字符集和編碼概念
- 掌握漢漢字 GB2312 編碼方式
- 掌握漢字 utf8 變長編碼方式
- 了解 BOM 標志和常見值
- Windows 代碼頁 code page 含義
相關基礎概念
細說編碼 、徹底理解字符編碼 和字符編解碼是了解字符編碼比較深入淺出的文章,以下快速了解相關概念,是后續內容的基礎。
字符集和編碼
-
ASCII(American Standard Code for Information Interchange)碼就是第一套通用的計算機編碼,它包含了英文字符,阿拉伯數字和一些常用符號,一共128個,占一個字節,第一位補0,例如常用的大寫字母A是65(01000001)。
-
"字符集"是字符到其標識代碼值的映射。ASCII 是128個字符映射到一個字節不同標志代碼上。傳統字符集使用8位代碼值或8位值組合來表示特定語言或地理區域中使用的字符的 Windows 代碼頁。
GB2312、GBK、Unicode 字符集
-
GB2312 就是中國國家標准總局制定的漢字字符集標准碼,GB 是國標的意思。實際上,GB2312 除了中文以外,還包含了拉丁字符,希臘字符,日文,俄語等等常見字符。
-
GB2312占據兩個字節,也就是說他能容納的字符數量為 216一共65536個。GB2312將所有字符分成了若干個96字符的組,每個組稱為區,字符所在的位置稱為區位,這樣,每個字符都有了對應的區位碼。
舉個例子:漢字“奇”在第38區,第70位,區位碼中3870。區號和位號分別加上 0xA0,所以漢字“奇”的GB2312編碼是 0xA0+38 0xA0+70 = 0xC6E6


-
GBK是GB2312的升級版,不止包含常用漢字,還包含了繁體,部首,生僻字等等,幾乎可以滿足所有使用漢字的場景。
-
Unicode 是一種全球字符編碼標准,當今計算機中最常用的字符集(字符集和編碼的概念區分並不嚴格)。新的 Windows 應用程序應使用 Unicode 來避免不同代碼頁的不一致,並有助於簡化本地化 unicode 查詢工具。
utf-8/16/32 編碼和 BOM 字節標記
-
utf-8/16/32 編碼:Unicode 是字符集,規定了每個字符對應的數值,utf則是具體的實現方式,用各種方法來存儲字符對應的數值,而根據各種實現方式的不同,又分為utf-8/16/32。
- utf-8 編碼:UTF-8就是以 8 位為單元對通用字符集進行編碼。utf8 是變長編碼,如果是1字節,它和Ascall碼是一樣的,多字節情況參考下面編碼過程:
UCS-2編碼(16進制) - UTF-8 字節流(二進制) 0000 - 007F 0xxxxxxx 0080 - 07FF 110xxxxx 10xxxxxx 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
漢字 “奇” unicode 編碼 0x5947, 5947 對應三個字節
5947 轉換成2進制: 0101 100101 000111 填充到utf8格式中:1110 0101 10 101110 10 000111 得到utf8碼: E5AE87
- utf-16 編碼:utf-16 的長度固定為 2 個或者 4 個字節,通常我們使用 2 個字節就可以了,它對應的就是 Unicode 中的基本平面 BMP,編碼就是 Unicode碼,不足 2 個字節的位數在前邊補0,同樣是漢字"安",它的 Unicode 碼是 0x5B89,所以 utf-16 碼也是 0x5B89。所以 ASCII 碼也會占據兩個字節,會有一部分空間浪費。
- 可以通過該【網址】(http://www.metools.info/code/utf8235.html)快速查詢 utf-8 編碼。
-
BOM:Byte Order Mark,字節序標記,這是固定的,判斷文本文件是哪一種Unicode編碼的標記。
表1:[代碼頁標志符]

Windows 終端代碼頁(code page)和舊版本控制台模式
-
代碼頁:大多數編寫的應用程序都以 Unicode 的形式使用 utf-16 編碼來處理字符數據。 但是,許多舊版應用程序將繼續使用基於代碼頁的字符[1]。
表2:代碼頁標志符
標志符 .net 名稱 其他信息 936 gb2312 ANSI/OEM 簡體中文 (中國、新加坡) ;簡體中文 (GB2312) 65001 utf-8 Unicode (UTF-8) -
舊版本控制台模式:舊版控制台模式是一種兼容性工具,旨在幫助用戶在 Windows 10 上運行較舊的命令行工具。 對於在默認 Windows 10 控制台體驗中未正確顯示或運行的任何命令行工具,此模式提供了一種粗粒度的解決方案,可將系統恢復到較舊版本的控制台托管體驗。舊版本和當前版本之間的主要已知差異是 UTF-8 的實現。 舊版主機在代碼頁 65001上提供最基本的 UTF-8 支持[2]。