自从“帧缓冲器应用编程”视频的上一版本以来,

  我们花了10多天调试STM32MP157板,4.19内核和5.4内核全部调试完毕!

  在调试的过程中,写了很多文档,做完之后会发布给大家。也许我们可以记录一个项目:

  如何把厂商SDK移植到自己的板上?

  这将在以后发生,

  从今天开始,魏老师继续录制发布视频。

  今天的文章发表:字符的编码方式,视频正在同步录制中。

   6.1字符的编码方法6.1.1编码和字体在电脑上,我们看到的字符“A”可能是这样的:

  它也可能看起来像这样:

  对于同一个TXT文件中的内容,在记事本上选择不同的字体时,字符会以不同的形状显示。

  所以TXT文件中保存的是角色的核心:它的编码值。在记事本上显示时,这些字符对应什么形状状态是由字符文件决定的。码值和字体是两回事。例如,A的代码值是0x41,但在屏幕上显示时可以使用不同的形状。

  什么是编码?是一个字符所代表的数字。电脑里的一切都是用数字来表示的,比如字符a,用0x01还是0x02来表示?我们用0x41来表示。当你去打开一个TXT文件,发现里面包含了值0x41,你就知道了:哦,这里有一个字符a。

  哪个数字用来代表一个字符?比如有很多标准。

   1.ASCII是“美国信息交换标准码”的缩写,美国信息交换标准码。

  毕竟电脑是西方人发明的。他们通常只用26个字母,区分大小写和标点符号不超过127个。每个字符一个字节就足够了。一个字节的7位可以代表128个数值,ASCII码的最高位永远是0。

  字符和数值之间的对应关系可以称为https://baike.baidu.com/item/ASCII.

  以下节选给你一个印象:

   2.ANSI强烈推荐阅读:https://www.cnblogs.com/malecrab/p/5300486.html

  使用记事本保存文件时,可以选择“ANSI”编码,但是没有“ASCII”,如下图所示。这是怎么回事?

   ASNI是ASCII的扩展,向下包括ASCII。ASCII字符仍然用一个字节表示,而非ASCII字符用两个字节表示。没有固定的ASNI代码,但它与“本地化”密切相关。例如,在中国大陆,ANSI的默认代码是GB2312;在香港、澳门和台湾,默认代码是BIG5。以数值“0xd0d6”为例,对于GB2312编码,表示“中等”;对于BIG5编码,它意味着“稗子”。所以对于ANSI编码的TXT文件,如果打开发现乱码,就要重新细分它的具体编码。

  例如,对于TXT文件,其中的值如下:

  用记事本打开后,选择不同的编码(或字符集),会有不同的显示,如下:

  只有在中国才会出现这些不相容的问题。对于不同的国家,它们默认的ANSI代码是不同的,所以同一个TXT文件在不同的国家很可能会出现乱码。

  根本原理是没有“统一编码”,所以解决方法自然是用“统一编码”:UNICODE。

   3.UNICODE在ANSI标准中,很多种类的字符都有自己的编码标准,比如简体中文的GB2312,繁体中文的BIG5。相同的数值对应不同的字符是不可避免的。例如,对于GB2312编码,值“0xd0d6”表示“中等”;对于BIG5编码,它意味着“稗子”。这导致用ANSI代码保存的文件不适合跨区域通信。

   UNICODE就是解决这类问题的方法:对于地球上的任何一个字符,都被赋予一个唯一的数值。

   UNICODE还是向后兼容ASCII,但是其他字符会有对应的值,比如“中”和“子”。它们的值分别是0x4e2d和0x7b22。

   UNICODE的取值范围是0x0000到0x10FFFF,有1,114,111,也就是一百多万个值,可以代表一百多万个字符,足够地球人使用。

   6.1.2编码实现所谓编码实现就是如何表示一个数值。太奇怪了。一个数值还能怎么表达?例如,“medium”的UNICODE值是0x4e2d。在TXT文件中是如何表示0x4e2d的?直接写0x4e2d?不会吧!

  比如在TXT文件中写2个字节的数据“0x2d0x4e”,是否可以用来表示“中”字?不要!它们对应于ASCII字符“-N”。

  问题的关键是:如何破题。在TXT文件中,2字节数据“0x2d0x4e”是作为一个整体处理还是分成2部分?

  所以需要用一定的技巧来表示数值,对应不同的编码实现。

  现在我们知道:

   1.在ASCII编码中,用一个字节表示一个字符,只用7位,最高位常数为0;

   2.在ANSI编码中,ASCII字符仍然用一个字节表示(BIT7为0),而非ASCII字符一般用两个字节表示,非ASCII字符的值都是1。

   3.UNICODE:这个有点复杂。让我们逐一解释。

  首先用记事本新建三个文件:utf-16_le.txt、utf-16_be.txt、utf-8.txt和bom_

  utf-8.txt,里面的内容都是“ab中”,保存时编码分别选择“UTF-16 LE”、“UTF-16 BE”、“UTF-8”、“带有BOM的UTF-8”,下图是其中一个例子:

  怎么表示一个UNICODE数值?

  1. 使用3个字节表示一个UNICODE

  不,太浪费。

  UNICODE的最大值是0x10FFFF,那使用3个字节来表示一个UNICODE数值?这当然是很省事的方法,但是会造成浪费,比如字符A的UNICOCDE值是0x41,难道也用“0x41 0x00 0x00”这3个字节来表示?

  2. UCS-2 Little endian/UTF-16 LE

  每个UNICODE只用3字节来表示有点浪费,那只用2字节呢?它可以表示2^16=65536个字符,全世界常用的字符都可以表示了。

  Little endian表示小字节序,数值中权重低的字节放在前面,比如字符“ab中”在TXT文件中的数值如下,其中的“a”使用“0x61 0x00”两字节表示;“b”使用“0x62 0x00”两字节表示;“中”使用“0x4e 0x2d”两字节表示。文件开头的“0xff 0xfe”表示“UTF-16 LE”。

  3. UCS-2 Big endian/UTF-16 BE

  Big endian表示小字节序,数值中权重低的字节放在后面,比如字符“ab中”在TXT文件中的数值如下,其中的“a”使用“0x00 0x61”两字节表示;“b”使用“0x00 0x62”两字节表示;“中”使用“0x2d 0x4e”两字节表示。文件开头的“0xfe 0xff”表示“UTF-16 BE”。

  4. UTF8

  在上面2种方法中,每一个UNICODE使用2字节来表示,这有3个缺点:表示的字符数量有限、对于ASCII字符有空间浪费、如果文件中有某个字节丢失,这会使得后面所有字符都因为错位而无法显示。

  使用UTF8可以解决上述所有问题。UTF8是变长的编码方法,有2种UTF8格式的文件:带有头部、不带头部。先举例,看下图:

  对于其中的ASCII字符,在UTF8文件中直接用其ASCII码来表示,比如上图中的0x61表示字符a、0x62表示字符b。上图中的3个字节“0xe4 0xb8 0xad”表示的数值是0x4e2d,对应“中”的UNICODE码。

  对于非ASCII字符,使用变长的编码:每一个字节的高位都自带长度信息。请看下图:

  上图中,0xe4的二进制是“11100100”,高位有3个1,表示从当前字节起有3字节参与表示UNICODE;

  0xb8的二进制是“10111000”,高位有1个1,表示从当前字节起有1字节参与表示UNICODE;

  0xad的二进制是“10101101”,高位有1个1,表示从当前字节起有1字节参与表示UNICODE;

  除去高位的“1110”、“10”、“10”后,剩下的二进制数组合起来得到“01001110001101”,它就是0x4e2d,即“中”的UNICODE值。

  使用UTF8编码时,即使TXT文件中丢失了某些数据,也只会影响到当前字符的显示,后面的字符不受影响。