python教程

当前位置:首页 > 计算机底层基础 > 当前文章

计算机底层基础

编码是什么?为何会有乱码?字符集与编码区别

2020-04-06 77赞 老董笔记

  编码引入

  我们用阿拉伯数字1代表只有一个事物。英国人用字母one代表只有一个事物!我们管老虎叫做老虎,英国人管老虎叫做tiger。描述同样的事物不同的人用了不同的方式。假定英国被你霸占了,你规定one代表老虎,那也无可厚非。老子曰:道可道,非常道。名可名,非常名。事物就在那里,变的是表示他的方法。这些方法可以看成编码。

  字符集的概念

  计算机底层硬件表示出来的信息只有无电压和有电压两种状态,我们用数字0和1描述,用一串0和1进行组合来表示不同的信息。 不同的字符要在计算机硬件中表示,需要转换为二进制值0和1的组合,二进制值和字符之间通过字符集进行映射。

  最初只有ASCII字符集,他是1个8位的二进制组合(1个字节),共定义了共 128 个字符,这是美国人最先使用的,如果只编写包含英文字符的程序,ASCII 是够用的。但是随着计算机普及,由于每个国家都有自己的字符,中国文字、日文、韩文等等都需要用计算机显示出来,所以上述字符集是远远不够的,为了让所有国家的字符能在计算机上显示,就需要扩展二进制组合的位数(多个字节),这样才能有更多的组合显示更多的文字。

  不同字符集的兼容问题

  人类陆陆续续定义处出很多字符集,如ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等,这其中难免出现兼容问题,同1个二进制组合方式在不同的字符集中代表的字符不一样,所以这也是个需要解决的问题。

  最终Unicode字符集一统天下,既能包含世界上所有的字符,也统一了字符和二进制的对应关系!我们可以把1个字符在字符集对应的二进制组合称为Unicode序号或者码点值

  字符编码

  按理说有了字符集就很美满了,需要哪个字符直接去找代表他的Unicode序号即可,在计算机中就用这个Unicode序号来存储。但是问题来了,Unicode字符集之所以能涵盖全世界的字符,因为他用的是多个字节来存储1个字符的二进制组合序号。 使用中如果把每个字符都用Unicode序号来存储的话,每个字符就占多个字节,这会耗费很多空间。

  为了更科学的存储节约空间,产生了编码方案,比较常见的就是UTF-8和GBK编码,他们是对Unicode序号进行了一次编码。在UTF-8中是可变长的字节存储字符,如果是a、b、c这种ASCII字符集中的字符就用单字节存储。

   比如:如果1个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间,0之后的所有部分(7个bit)代表在Unicode中的序号。

   UTF-8和GBK编码并没有涵盖整个Unicode的字符,实际工作中碰到有些特殊字符会报错,但他们是较为流行的一种编码方案,方便大部分群体使用!

  为何有乱码

  乱码是不同编码方案混淆使用的结果(同样是一句话,你按照不同的方式断句,结果也不一样)。存储文字的时候按照一种编码存储,而显示文字的时候按照另一种编码显示!假设在utf-8编码里面4个电压信号算作一个文字编码。0101代表我,1010代表们,那么0101  1010就是我们,我们以utf-8的形式存储完毕。而在GBK里面3个电压信号算一个编码,此时解码按照三个一组来解码,就是010  110  10,而这个序列在GBK里面谁知道是什么玩意,或许根本就木有,当然就是乱码。

  特别注意1:

  在国内用windows电脑,在其cmd这个终端下是以GBK的形式解码显示字符,一些文本编辑器比如sublime默认是以utf-8打开文件。所以大家在选择终端的时候要了解他到底是以什么方式显示字符的,否则能会遇见一些奇葩事,这和系统本身及终端本身特性有关。

  特别注意2:

  所有的系统、编程语言都支持unicode,cmd也不例外!我们练习python3虽然都是保存的utf-8编码的py文件,但在cmd下却可以正常显示!因为python解释器在内存自动给转成了unicode来显示。python2版本不具备这个操作,所以python2版本在cmd下经常会乱码。python2濒临淘汰,不用管他了。

感兴趣直接点击图片获取>>

文章评论

编码是什么?为何会有乱码?字符集与编码区别文章写得不错,值得赞赏