[Python学习日记-22] Python 中的字符编码(下)

[Python学习日记-22] Python 中的字符编码(下)

简介

编码的战国时代

Unicode 和 UTF

现代计算机系统通用的字符编码工作方式

简介

        在[Python学习日记-21] Python 中的字符编码(上)中我们讲了字符编码中的 ASCII 码和 GB2312/GBK,本片我们来讲述当时犹如雨后春笋般的编码战国时代和万国码时代,以及 Python 在这时代背景下的一些特性

编码的战国时代

        之前我们讲了 GB2312/GBK 编码,其实这个只是中国的情况,世界上有很多国家在开始使用计算机时也面临该状况,所以很多国家都开发了自己的字符编码以适应本国的国情,包括但不完全的有以下类型:

  • ASCII(美国等使用英语的国家,占1个字节,只支持英文)
  • GB2312/GBK(中国字符,占2个字节,支持6700+汉字,而GBK是GB2312的升级版,支持21000+汉字)
  • Shift-JIS(日本字符)
  • ks_c_5601-1987(韩国编码)
  • TIS-620(泰国编码)

常用编码介绍一览表:

编码制定时间作用所占字节数
ASCII1967年表示英语及西欧语言8bit/1bytes
GB23121980年国家简体中文字符集,兼容 ASCII2bytes
Unicode1991年国际标准组织统一标准字符集2bytes
GBK1995年GB2312 的扩展字符集,支持繁体字,兼容 GB23122bytes
UTF-81992年不定长编码1-3bytes

        各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。例如有一个日本进口的游戏(日本默认使用 Shift-JIS),往自己电脑上一装(中文版的 Windows 字符编码默认是 GBK),就显示乱码了。

        因此极大的阻碍不同国家之间的信息传递,这个乱局最终是联合国出面解决的,于是就诞生了下面要说的 Unicode 和 UTF

Unicode 和 UTF

一、Unicode

         上面讲到,由于各国之间都开发出了自己的字符编码,导致不同国家之间的信息传递有极大的阻碍。所以 Unicode 编码应运而生,Unicode 编码把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode 编码使用2到4个字节,并且已经收录136690个字符,并还在一直不断扩张中。同时 Unicode 编码标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持 Unicode 编码。

特点:

  1. 支持全球所有的语言
  2. 可以跟各种语言的编码自由转换,也就是说,即使你 GBK 编码的文字,想转成 Unicode 编码也很容易

        为何 Unicode 编码需要与其他语言的字符编码相互转换呢?这是个历史问题,以中文编码为例,GB2312 最早是在1980年出现的,而 Unicode 编码是1990年才出现的,那在这十年之间无数的计算机应用开发都是使用 GB2312 来开发的,如果突然间要求所有的计算机应用都使用该编码,那几乎就是要求所有使用 GB2312 来开发的计算机应用推倒重来,这换做你应该也会反对吧;并且 GB 系列编码就像汉语在国内一样,而 Unicode 编码就像国际通用语言英语一样,而我们在国内沟通时基本不需要使用英语吧,所以也没有很强烈的需要要求把 GB 系列编码转换成 Unicode 编码。

        于是联合国为了推广 Unicode 编码还做了以下努力:

  1. 联合国要求全球计算机厂商出厂都支持 Unicode
  2. Unicode 与所有语言编码都做了对应关系(这也是为什么 Unicode 可以与各种语言编码可以自由转换的原因)

        而目前为止大多数的计算机应用都支持 Unicode 编码。下图就是 Unicode 编码跟中文编码的对应关系

二、UTF

        但是新的问题又出现了!如果统一成 Unicode 编码,乱得问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用 Unicode 编码比 ASCII 码的存储空间需要多一倍,由于计算机的内存比较大,并且字符事在内容中表示时也不会特别大,所以内存可以使用 Unicode 编码来处理,但是存储和网络传输时一般数据都会非常多,那么这多的一倍的存储空间将是无法接受的。

        为了解决存储和网络传输的问题,于是出现了 UTF(Unicode Transformation Format),即:对 Unicode 编码进行转换,以便于在存储和网络传输时可以节省空间,UTF 有以下版本:

  • UTF-8(主流):使用1、2、3、4个字节表示所有字符,优先使用1个字符、无法满足则增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
  • UTF-16:使用2、4个字节表示所有字符,优先使用2个字节,否则使用4个字节表示
  • UTF32:使用4个字节表示所有字符

        总的来说,UTF 是为 Unicode 编码而设计的一种,在存储和传输时节省空间的编码方案。如果你要传输的文本包含大量英文字符,用 UTF-8 编码就能节省空间,ASCII、Unicode、UTF-8之间的对应如下表所示

字符ASCIIUnicodeUTF-8
A0100000100000000 0100000101000001
x01001110 0010110111100100 10111000 10101101

        从上面的表格还可以发现,UTF-8 编码有一个额外的好处,就是 ASCII 码实际上可以被看成是 UTF-8 编码的一部分,所以大量只支持 ASCII 码的历史遗留软件可以在 UTF-8 编码下继续工作。

现代计算机系统通用的字符编码工作方式

        目前我们已经对 ASCII、Unicode 和 UTF-8 有了了解,那我们现在总结一下现代计算机系统通用的字符编码工作方式。

        在计算机内存中,统一使用 Unicode 编码,当需要保存到硬盘或者需要传输的时候,就转换为 UTF-8 编码。例如用记事本编辑的时候,从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里,编辑完成后,保存的时候再把 Unicode 转换为 UTF-8 保存到文件。如下图所示

        值得一提的还有,如果你的系统编码格式是 UTF-8 编码,而你所写的程序为 GBK 编码,那么也会产生乱码,这是因为 UTF-8 与 GBK 并没有直接关系,之所以他们能转换是因为 Unicode 作为中介,具体如下图所示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JoveZou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值