上面这种乱码的形式我特别映像深刻,刚好今天在学习的时候碰到了,便记录下来。
先理解电脑中是怎么保存数据的。
电脑中的数据
我们知道,电脑所保存的数据,都是010101 的二进制数据。常常在学数据结构的时候,都知道程序 = 算法 + 数据结构。而数据结构就是相当于我们这里的二进制了。
计算机怎么识别字符串?
我们都知道,计算机只能识别二进制数,在它面前都是0和1 两个数字,那怎么让不同的 0 和 1 组成来表示不同的数据呢?
这里典型的我们都知道 ASCII 码,这里的 ASCII 码就好比一个字典,用 8 位二进制,来存储着 128 个不同的数,对应着 128 个不同的字符。比如小写字母 a 在 ASCII 里面,就是第 97 个,也就是二进制 0110 0001。那么这里,我们的计算机就能识别了。
字符集
表示的可以是字符的一个集合。像“中文”就是一个字符集,比如“第一版《新华字典》里面出现的所有汉字”,这是一个字符集。这样,我们才能明确知道,一个字符在不在这个集合里面。比如,我们日常说的 Unicode,其实就是一个字符集,包含了 150 种语言的 14 万个不同的字符。
字符编码
则是对于字符集里的这些字符,怎么一一用二进制表示出来的一个字典。上面说的 Unicode,就可以用 UTF-8、UTF-16,乃至 UTF-32 来进行编码,存储成二进制。所以,有了 Unicode,其实我们可以用不止 UTF-8 一种编码形式。
锟斤拷烫烫烫的由来
同样的文本,采用不同的编码存储下来。如果另外一个程序,用一种不同的编码方式来进行解码和展示,就会出现乱码。这就好像两个军队用密语通信,如果用错了密码本,那看到的消息就会不知所云。在中文世界里,最典型的就是“手持两把锟斤拷,口中疾呼烫烫烫”的典故。
首先,“锟斤拷”的来源是这样的。如果我们想要用 Unicode 编码记录一些文本,特别是一些遗留的老字符集内的文本,但是这些字符在 Unicode 中可能并不存在。于是,Unicode 会统一把这些字符记录为 U+FFFD 这个编码。如果用 UTF-8 的编码 的格式存储下来,就是\xef\xbf\xbd。如果连续两个这样的字符放在一起,\xef\xbf\xbd\xef\xbf\xbd,这个时候,如果程序把这个字符,用 GB2312 的方式进行 解码,就会变成“锟斤拷”。这就好比我们用 GB2312 这本密码本,去解密别人用 UTF-8 加密的信息,自然没办法读出有用的信息。
而“烫烫烫”,则是因为如果你用了 Visual Studio 的调试器,默认使用 MBCS 字符集。“烫”在里面是由 0xCCCC 来表示的,而 0xCC 又恰好是未初始化的内存的赋值。于是,在读到没有赋值的内存地址或者变量的时候,电脑就开始大叫“烫烫烫”了。
声明:该文章是学习笔记和学习心得。以上的部分图片来源于极客时间的”深入浅出计算机组成原理“的课程