当前位置: 首页 > 科技观察

为什么会有乱码?什么是编解码器?为什么会有这么多字符集?

时间:2023-03-12 06:07:42 科技观察

前言乱码这个东西相信大家都遇到过。今天,闺蜜三外急忙跑到我面前:“老婆,我的idea怎么输出的是乱码?”是的,不过三外不愧是我蘑菇街的女朋友。好奇心跟我一样,跟我来。那为什么会出现乱码呢?什么是编码,什么是解码?什么是字符编码,什么是字符集?为什么是统一码?UTF-8和GBK有什么区别?为什么会出现乱码?我们知道计算机存储的只是由0和1组成的字节流,但是光靠数字是不能满足我们的需要的。我们还需要文字处理等,但是计算机只懂数字,所以我们需要告诉计算机什么数字代表什么字符。比如我指定0000代表A,0001代表B,计算机就知道了,那么如果我要将AB这两个字符存入计算机,实际存入的是00000001,其实就相当于自定义了一个每个字符的唯一代码。但这是我的指定。不同的人有不同的想法。比如小明喜欢1000代表A,1111代表B,然后小明的电脑按照他指定的编码方式存储,就是10001111,然后传到我的电脑上。我得到的是10001111,根据我的代码,可能是%&,是乱码。所以,乱码的本质就是编解码实现不对应。可能有些同学对编码和解码的概念不太熟悉,我来解释一下:编码:其实就是将字符按照一定的格式转换成字节流的过程。解码:就是把字节流解析成字符。可见,随机编码会导致各自电脑无法正确解析的情况,所以需要一个标准,大家按照那个标准来规定字符和数字的对应关系。标准字符编码美国国家标准协会ANSI制定了一个标准,即美国信息交换标准码(ASCII),它规定了常用字符集的集合以及对应的数字编号,比如65代表A。ASCII实际上是一个7位代码,用二进制代码表示为0000000~1111111,但是1个字节就是8位,所以一般用8位来存储。可以看出ASCII代表128个字符,其实就是美国的编码。如果你看看同样说英语的英国,ASCII上没有井号。还有人家的韩文、日文等等,更何况是我们的中文。1个字节最多只能表示256个字符,对我们来说不够用,所以需要扩充。比如GB2312就是国家标准总局发布的《信息交换用汉字编码字符集》,后来又发布了GBK。这个K表示扩张。在GB2312的基础上,增加了繁体字等诸多字符。所以说每个国家都有自己的标准,因为语言不同,字符集的不同,使得计算机之间的文档交流变得非常困难,于是大家又开始了标准化的浪潮。比如美国的ANSI组织制定了ANSI标准的字符编码,实际上就是平台默认的编码。比如中国的操作系统使用GBK,美国的操作系统使用ASCII。这些标准字符集预装在操作系统中。但是这样只能解决一份文档和一种字符编码的情况。假设我的文档有日文、法文、德文、俄文、中文,你说呢?于是Unicode创造了Unicode,也称为Unicode、UniversalCode、Unicode。Unicode字符集涵盖了人类目前使用的所有字符,并对每个字符统一编号并赋予唯一的字符代码。你看,这种事情必须得有人去做,不然就不统一了。我在这里解释几个术语,让大家更清楚。字符:其实就像英文字母,或者我们中文叫字符字符集:也就是字符和数字对应的集合字符码:就是字符集中字符对应的数字,或者说数字,例如在ASCII字符集中,A字符编码为65字符编码:根据字符集中字符与数字的映射关系,转换为字节流的实现与之前Unicode的编码略有不同,这解耦了字符集和编码的实现。以前的编码如ASCII编码、GBK编码等,它们的字符集和编码实现是相互捆绑的。你可以理解为前面的编码其实就是一个查找表。有一个固定的表来存储字符和对应的固定二进制,比如A对应的数字是65,它的二进制序列是01000001。不像Unicode,它把字符集和字符编码分开。比如A对应的数是65,但是对应的二进制序列不一定相同。这取决于具体的字符编码。如果是UTF-8编码就是01000001,或者UTF-16编码(bigendian)就是0000000001000001。这实际上就是我们现在使用UTF-8而不是UTF-16的原因。我们可以看到UTF-16编码存储效率低,至少使用两个字节,而像C语言很多函数都会使用0x00字节作为字符串的终止符来解析,所以我创建了一个UTF-8,每个字符使用1~4字节编码,长度可变。我不会谈论如何编码它。只是检查一下。.终于,到这里,我们已经弄清楚了乱码的根源,也知道为什么会有那么多的字符编码了。毕竟,有很多种语言。ASCII一开始就发布了,但是其他国家不够用,所以都扩充了。但编码过多的国家之间很难做到统一和兼容,所以后来国际组织制定了Unicode字符集,将所有字符统一编排,将字符集和编码实现分开,使编码更灵活。来。对了,为什么英文没有乱码,是因为大部分字符集都是基于ASCII扩展的,所以都是兼容ASCII的。