加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_汕头站长网 (https://www.0754zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

字符编码(一)|字符编码终极指南

发布时间:2022-10-11 12:58:23 所属栏目:Linux 来源:
导读:  使用python的过程中,或多或少都会接触一些字符编码的问题,网上提到比较多的是python2中会有各种奇怪的编码问题,很多人都会说换成python3之后就没有编码的烦恼了,但事实上不是这样的。只能说python2因为自身设
  使用python的过程中,或多或少都会接触一些字符编码的问题,网上提到比较多的是python2中会有各种奇怪的编码问题,很多人都会说换成python3之后就没有编码的烦恼了,但事实上不是这样的。只能说python2因为自身设计问题产生了更多编码的问题,不能说换用python3之后就能彻底摆脱编码烦恼了。既然因为历史原因,产生了这么多种编码,人们使用过程中也不能保持一致,那么编码问题将会一直存在下去。要想不被编码问题困扰,最好的方法就是彻底了解其背后的机制。
 
  虽然编码问题网上已经有了大量文章,但是没有一篇文章能把所有的问题涵盖,所以我写了这个系列。我看了网上非常多关于字符编码的博客和回答,结合自己的使用,尽可能全地总结平时可能遇到的编码问题。有些普遍的问题很多博客都说的很清楚了我就贴上链接再简单叙述一下了。
 
  这个系列分为以下几个部分
 
  本文包括前三个部分
 
  编码的起源
 
  几乎每一篇讲编码的文章都会说一遍编码的起源,详细的在这里就不多说了,可以参考下面链接
 
  总结起来就是
 
  常见编码
 
  这里介绍一下我们平常会经常见到的编码,了解了这些常见编码,在遇到时就大概知道哪些编码是做什么的,比如下面文本编辑器sublime中reopen可以使用的编码表
 
  1.ASCII编码
 
  用8个比特(一个字节),即8位的二进制数来表示一些符号。其中包含了26个英文字母大小写字母、0-9数字,以及键盘上能看到的!@#$%^&*()_+{}|?等符号。因为8位之首一直是0,所以一共可以表示128个。
 
  这是最初产生的编码,所以之后的所有编码几乎都兼容这种
 
  2.EASCII、ISO/8859-1、Latin-1、windows 1252
 
  EASCII是ASCII编码的扩展,将8个比特数值全部填满,可以表示256个数,加入了一些公式符号、希腊字母等。不过EASCII并不表示某一种编码方式,有很多种不同的扩充方式。ISO/8859-1是其中一种,又名Latin-1。windows 1252是windows对应设计的一种。
 
  3.GBK、GB2312
 
  为了表示中文字符,中国人最初指定了GB2312,可以表示绝大多数中文字符,但是仍有少部分不能表示。之后又扩充产生了完整表示中文字符的GBK编码。GBK使用两个字节(16位二进制数)来表示字符。
 
  在windows操作系统下,我们经常看到GBK这种编码,很多软件都默认用这个编码来保存和读取文件。比如记事本默认使用ANSI保存文件,常常就是使用GBK保存的文件。(ANSI后面会具体讲)
 
  4.Unicode
 
  这是国际组织制定的全球统一编码,可以表示任意字符,通常占用两个字节。其实Unicode只是将每个字符对应一个数字使字符得到唯一标示,它没有真正用于计算机存储,真正根据Unicode设计用于存储的是下面的UTF系列编码。
 
  5.UTF-8
 
  UTF-8可以说是当前最推崇的一种编码方式,可以表示任意字符,同时它一种“可变长”的编码,即表示不同字符的字节数量是不相同的。比如英文就延续ASCII使用一个字节,中文是3个字节,更不常用的字符可能是4-6个字节。
 
  经常和UTF-8一起提到的还有
 
  这里只需要知道
 
  这部分没那么重要,而且有点乱,更详细的内容见下面这些链接
 
  6.ANSI
 
  这是windows记事本中特有的,记事本保存文本文件时默认使用的是ANSI,其看下面保存时的界面,可以有4种选择
  
  默认使用ANSI,但其实是使用GBK保存的。经常默认使用GBK而不是utf-8保存打开文件应该是windows被诟病的一个点(相比于mac和linux)。有的人就会问为什么windows这么反人类,不用兼容性好的utf-8,但是这有点冤枉windows了。现在的windows其实使用的就是unicode,但是很多软件用的不是unicode,为了兼容那些软件,windows设下这样的规定:设置一个默认编码,遇到一个字符串如果使用unicode就用unicode,不使用的就用这个默认语言来解释。而这个默认语言在不同windows语言版本中是不一样的,在简体中文版是GBK,在日语的windows系统中就是支持日语的编码。ANSI就是这个默认编码,因此在这里使用ANSI就相当于使用GBK。
 
  更多内容参考这个回答和这个回答
 
  关于记事本还要说明以下几点
 
  本节这些编码的更详细解释见这个回答
 
  上面我们介绍了各种编码如何演变以及常见编码,之后几个部分就来看一下哪些情况下会遇到乱码问题。
 
  文件保存与打开中的编码问题
 
  本节分为如下部分
 
  明确存储原理
 
  首先要明确,我们人眼看到的英文字母、文字等计算机是无法识别的,也无法直接处理和储存这样的内容,所以需要将这些字符编码成计算机可以识别的二进制数进行存储。
 
  比如在记事本中输入A中,使用UTF-8保存文件,记事本会将这些字符按照UTF-8的规则编码成01000001 11100100 10111000 10101101这样的二进制数,将这些数存到硬盘中。之后某一天我们想看文件中的内容,用记事本打开,它会将这一串二进制数又解码为我们能看懂的字符串。因为在UTF-8下二进制编码和字符是一一对应的,所以存储和打开时都使用UTF-8就不会出现乱码。
 
  而如果我们读取时使用EASCII,它的每个字符对应一个字节,即上面存储的4个字节会被解码成4个字符,显然不是我们最开始保存的A中了,这种不一致就是乱码。这段二进制数放在EASCII中可能得到的字符我们还认得,而在有的编码方式中可能就对应着非常生僻的符号,全篇解码出来都是这种看不懂的东西,这就是我们脑中最直观的所谓乱码了。
 
  还可能你使用的解码方式中没有这段二进制数据对应的字符,此时就会报错。因为一种编码方式占用一些字节数,这些字节可以表示的字符数量超过了当前需要表示的字符数量,就会有一些二进制数不对应任何字符,此时要将这些二进制数转成字符而报错。
 
  txt文件不同编码方式保存与打开试验
 
  首先推荐写代码时不要使用windows自带的记事本,它对写代码的各种支持都不好。可以选择自己称手的文本编辑器,我用的是sublime text3,它一个优点是打开文件非常快。这个文本编辑器支持以各种编码打开或保存文件,所以这里拿这个编辑器对编码问题进行测试。
 
  为了更直观地体会乱码,这里使用windows自带的记事本和文本编辑器sublime text进行对比。
 
  实验方法:用记事本写下一段中文保存,再用sublime text打开,看结果。这里输入写下一段话很长的话再长一点
 
  为了看使用不同编码方式打开结果,用sublime打开后可以点击 file-reload with encoding(没有这个选项的看下一部分)来更换编码方式,选择GBK(中文简体)就正常显示,选择BIG5(中文繁体)发现文本乱码了,选择CP932(日文)报错了。
  
  sublime中关于编码的选项解释
 
  1.选项说明。sublime打开一个文件使用什么编码方式也是靠猜,而保存一个文件默认方式是UTF-8。它本身是不支持GBK解码的,刚下载sublime时应该是没有reload with encoding和set file encoding to的,只有reopen with encoding和save with encoding。reopen with encoding让我们可以在打开文件时指定用什么方式解码,但是这里没有GBK,要想解码GBK就只好安装ConvertToUTF8这个插件(如何安装百度一下),它提供了reload with encoding选项,也是表示用什么编码解码文件,这里提供了简体中文(GBK)、繁体中文、日文等编码。reload和reopen的功能其实是一样的,只是支持的编码方式不一样。
 
  安装好插件后,大多数时候用记事本编辑的中文,用sublime直接打开都不会乱码,是因为它根据存储的二进制数可以猜出要用GBK来打开。但是有的时候还是不行,用记事本编辑的什么,在sublime中打开就会乱码,因为它识别不出来是GBK,使用了UTF-8来解码,这时就要人为去选择reload with encoding中的GBK,就可以正常显示了。
 
  2.在使用过程中发现一个奇怪的现象:比如打开一个中文文件,默认正常显示linux编码,这是选择reload with encoding中的BIG5和CP932等都会出现乱码,这是正常的,而选择UTF-8没反应,正常不也应该乱码吗?此时如果用reopen with encoding中的所有选项都没反应,然而事实上都应该乱码才对。
 
  摸索了很久发现一个规律,就是如果打开时默认使用的是reload with encoding中的编码,想切换成UTF-8或者reopen with encoding中的编码,需要这样做
 
  知道这点之后我们就可以自由地对一些文本使用各种各样的编码方式进行解码了,会发现即使是乱码很多种编码的结果都是一样的,说明这些是相似的编码方式。
 
  3.如何改变文件编码。比如用记事本保存默认用的GBK编码,可以在sublime中打开将文件编码方式转变成UTF-8。sublime自带的选项是save with encoding,这里也不支持将文件转变成GBK进行保存,于是ConvertToUTF8这个插件又增加了一个选项set file encoding to可以保存为GBK,这个设置完要再点一下保存。
 
  这里要说明一点,比如当前显示中文字符,用的是GBK,你想换成UTF-8编码,它的内部原理是这样的
 
  如何知道一个文件的编码
 
  对于一个未知的文件,我们不能准确知道它的正确解码方式,毕竟软件也都是靠猜,因为很多种解码方式都可以得到一个结果,有些结果在我们眼中叫做乱码,但在计算机眼中都是一样的,所以它无法辨别人眼到底能识别的是哪种结果。
 
  我们能知道的只有
 
  首先我们可以看出当前软件使用什么方式进行的解码
 
  其中左边一个,右边一个。左边对应的是插件里的编码,右边对应的是sublime自带的。看你打开文件时使用了什么编码,如果是用GBK,那么右边显示的编码就完全没用不用看,如果是用reopen中的编码,则左边的不用看。
 
  比如一个中文文件,我们使用UTF-8解码,发现正常显示中文了,说明我们的解码方式正确,万事大吉。如果乱码了,说明文件不是用UTF-8编码的,这时是无法得知确切编码的,只能猜。这个文件是一个中国同学发给我的,他可能用的是GBK,于是去试GBK。不行的话可能再想这个文件最初是一个日本人创建的辗转到我这里来,于是再试日本的编码。如果都不行就没辙了,或者一个个试下来。
 
  R文件乱码问题
 
  在weindows下,R语言中无论是R还是rstudio,如果有中文注释都是使用GBK进行保存。但是最好将打开和保存文件设置为默认UTF-8,这在rstudio中是可以设置的。R里面应该是不能设置的。
 
  如果要和别人一起完成工作,他的电脑是mac,发给你的R文件都是utf-8编码的,你打开的话中文(比如注释)就会乱码,所以最好设置默认UTF-8。但是我们在rstudio设置之后,如果去打开以前的R文件,其中的中文也会乱码;那些没有设置过的windows小伙伴发来的.R文件也会出现中文乱码,但是这不是不换UTF-8的理由。如果你要和mac系统的人合作,同时要和日本人合作,和韩国人合作,他们默认保存的是UTF-8、日本设计的编码、韩国设计的编码,而你使用的是中国设计的编码GBK,遇到编码不兼容问题,最后商讨的结果一定是大家都换UTF-8来统一,所以早换晚换都要换,两个人编码不一样一定是非UTF-8的妥协。早一点换会让你电脑中GBK的文件少一些,之后修改编码方便一些。
 
  在rstudio中修改默认编码的方式:tool-global options-code-saving-change选择UTF-8
 
  设置完我们用R和rstudio进行试验
 
  在R中编辑脚本保存后用rstudio打开,

  在rstudio中选择reopen with encoding,选择GB2312就可以正常显示中文了。如果用R打开rstudio的UTF-8应该是没有方法进行转化的,所以还是全用rstudio就好。
 
  在rstudio中也可以选择save with encoding改变文件的编码方式。
 
  python脚本开头提示
 
  我们经常会看到一些python脚本文件(.py文件)最开始两行总是这样的
 
  #!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  其中第一行是在Linux/OS X中声明这是一个可执行的python程序,在windows下无用,可以忽略。
 

(编辑:云计算网_汕头站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!