VS2019 visual studio 终端乱码01 - 相关的基础概念


本文作者在使用 VS2019 调试 python 程序过程中,终端打印中文出现乱码。尝试从网络上收集解释,发现对乱码问题缺乏系统阐述,且每个解决均缺乏相关背景概念,不利于遇到同样问题的用户排查问题。因此本来的小随笔转换成了系列文章。

该系列主要四个部分组成:


➡️ VS2019 visual studio 终端乱码01 - 相关基础概念


VS2019 visual studio 终端乱码02 - 查看修改终端编码


VS2019 visual studio 终端乱码03 - VS中查看修改文件编码


VS2019 visual studio 终端乱码04 - 乱码案例


本节目标

  1. 明确字符集和编码概念
  2. 掌握汉汉字 GB2312 编码方式
  3. 掌握汉字 utf8 变长编码方式
  4. 了解 BOM 标志和常见值
  5. Windows 代码页 code page 含义

相关基础概念

细说编码 、彻底理解字符编码 和字符编解码是了解字符编码比较深入浅出的文章,以下快速了解相关概念,是后续内容的基础。

字符集和编码

  1. ASCII(American Standard Code for Information Interchange)码就是第一套通用的计算机编码,它包含了英文字符,阿拉伯数字和一些常用符号,一共128个,占一个字节,第一位补0,例如常用的大写字母A是65(01000001)。

  2. "字符集"是字符到其标识代码值的映射。ASCII 是128个字符映射到一个字节不同标志代码上。传统字符集使用8位代码值或8位值组合来表示特定语言或地理区域中使用的字符的 Windows 代码页。

GB2312、GBK、Unicode 字符集

  1. GB2312 就是中国国家标准总局制定的汉字字符集标准码,GB 是国标的意思。实际上,GB2312 除了中文以外,还包含了拉丁字符,希腊字符,日文,俄语等等常见字符。

  2. GB2312占据两个字节,也就是说他能容纳的字符数量为 216一共65536个。GB2312将所有字符分成了若干个96字符的组,每个组称为区,字符所在的位置称为区位,这样,每个字符都有了对应的区位码。
    举个例子:汉字“奇”在第38区,第70位,区位码中3870。区号和位号分别加上 0xA0,所以汉字“奇”的GB2312编码是 0xA0+38 0xA0+70 = 0xC6E6

汉字“奇”区位码
图1 汉字“奇”区位码
汉字“奇”的GB2312编码
图2 汉字“奇”的GB2312编码
  1. GBK是GB2312的升级版,不止包含常用汉字,还包含了繁体,部首,生僻字等等,几乎可以满足所有使用汉字的场景。

  2. Unicode 是一种全球字符编码标准,当今计算机中最常用的字符集(字符集和编码的概念区分并不严格)。新的 Windows 应用程序应使用 Unicode 来避免不同代码页的不一致,并有助于简化本地化 unicode 查询工具。

utf-8/16/32 编码和 BOM 字节标记

  1. 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 编码。
  2. BOM:Byte Order Mark,字节序标记,这是固定的,判断文本文件是哪一种Unicode编码的标记。

    表1:[代码页标志符]

常见编码 BOM 码

Windows 终端代码页(code page)和旧版本控制台模式

  1. 代码页:大多数编写的应用程序都以 Unicode 的形式使用 utf-16 编码来处理字符数据。 但是,许多旧版应用程序将继续使用基于代码页的字符[1]。

    表2:代码页标志符

    标志符 .net 名称 其他信息
    936 gb2312 ANSI/OEM 简体中文 (中国、新加坡) ;简体中文 (GB2312)
    65001 utf-8 Unicode (UTF-8)
  2. 旧版本控制台模式:旧版控制台模式是一种兼容性工具,旨在帮助用户在 Windows 10 上运行较旧的命令行工具。 对于在默认 Windows 10 控制台体验中未正确显示或运行的任何命令行工具,此模式提供了一种粗粒度的解决方案,可将系统恢复到较旧版本的控制台托管体验。旧版本和当前版本之间的主要已知差异是 UTF-8 的实现。 旧版主机在代码页 65001上提供最基本的 UTF-8 支持[2]。


  1. https://docs.microsoft.com/zh-cn/windows/console/legacymode ↩︎

  2. 一次性搞懂字符集,编码,Unicode,Utf-8/16,BOM... ↩︎

posted @ 2022-04-21 17:37  Oddpage  阅读(1233)  评论(0)    收藏  举报