Python基础 E-01 字符编码

字符编码

一、编码格式

1.1、ASCII码

1.1.1、产生的原因
  • 在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。

美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。

1.1.2、ASCII编码

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码。使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。

  • 0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
  • 32~126(共95个)是字符(32是空格)。
  • 48~57为0到9十个阿拉伯数字。
  • 65~90为26个大写英文字母,
  • 97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添0;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

  • 这张表就是计算机显示各种文字、符号的基石呀

在这里插入图片描述

1.1.3、GB2312 & GBK

英文问题是解决了, 我们中文如何显示呢? 美国佬设计ASSCII码的时候应该是没考虑中国人有一天也能用上电脑, 所以根本没考虑中文的问题,上世界80年代,电脑进入中国,把砖家们难倒了,妈的你个一ASSCII只能存256个字符,我常用汉字就几千个,怎么玩???勒紧裤腰带还苏联贷款的时候我们都挺过来啦,这点小事难不到我们, 既然美帝的ASCII不支持中文,那我们自己搞张编码表不就行了, 于是我们设计出了GB2312编码表,长成下面的样子。一共存了6763个汉字。

在这里插入图片描述

这个表格比较大,像上面的一块块的文字区域有72个,这导致通过一个字节是没办法表示一个汉字的(因为一个字节最多允许256个字符变种,你现在6千多个,只能2个字节啦,2**16=65535个变种)。
有了gb2312,我们就能愉快的写中文啦。
但我们写字竟然会出现中英混杂的情况,比如“我是小猿圈,我的英文名叫Apeland.”, 这种你怎么办?这就要求你必须在gb2312里同时支持英文,但是还不能是2个字节表示一个英文字母。人家ASCII用一个字符,你用2个,那一个2mb大小的英文文档只要一改编码,就立刻变成4mb, 太坑爹,中国人你有钱也不能这么造呀。 所以中国砖家们又通过神奇手段兼容了ASSCII, 即遇到中文用2个字节,遇到英文直接用ASCII的编码。怎么做到的呢?
如何区别连在一起的2个字节是代表2个英文字母,还是一个中文汉字呢? 中国人如此聪明,决定,如果2个字节连在一起,且每个字节的第1位(也就是相当于128的那个2进制位)如果是1,就代表这是个中文,这个首位是128的字节被称为高字节。 也就是2个高字节连在一起,必然就是一个中文。你怎么如此笃定?因为0-127已经表示了英文的绝大部分字符,128-255是ASCII的扩展表,表示的都是极特殊的字符,一般没什么用。所以中国人就直接拿来用了。
自1980年发布gb2312之后,中文一直用着没啥问题,随着个人电脑进入千家万户,有人发现,自己的名字竟然打印不出来,因为起的太生僻了。
于是1995年, 砖家们又升级了gb2312, 加入更多字符,连什么藏语、维吾尔语、日语、韩语、蒙古语什么的统统都包含进去了,国家统一亚洲的野心从这些基础工作中就可见一斑哈。 这个编码叫GBK,一直到现在,我们的windows电脑中文版本的编码就是GBK.

1.1.4、Unicode

编码混战时代
中国人在搞自己编码的同时,世界上其它非英语国家也得用电脑呀,于是都搞出了自己的编码,你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,
各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。之前你从玩个日本游戏,往自己电脑上一装,就显示乱码了。
这么乱极大了阻碍了不同国家的信息传递,于是联合国出面,发誓要解决这个混乱局面。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode 2-4字节 已经收录136690个字符,并还在一直不断扩张中…
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。

a、Unicode特定

Unicode有2个特点:

  • 支持全球所有语言
  • 可以跟各种语言的编码自由转换,也就是说,即使你gbk编码的文字 ,想转成unicode很容易。

为何unicode可以跟其它语言互相转换呢? 因为有跟所有语言都有对应关系哈,这样做的好处是可以让那些已经用gbk或其它编码写好的软件容易的转成unicode编码 ,利于unicode的推广。 下图就是unicode跟中文编码的对应关系

在这里插入图片描述

1.1.5、UTF-8

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,由于计算机的内存比较大,并且字符串在内容中表示时也不会特别大,所以内容可以使用unicode来处理,但是存储和网络传输时一般数据都会非常多,那么增加1倍将是无法容忍的!!!
为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode字符进行转换,以便于在存储和网络传输时可以节省空间!

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

总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。

如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:
在这里插入图片描述

从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。
搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
在这里插入图片描述

常用编码介绍一览表

[外链图片转存失败(img-30qxLU26-1569071474879)(evernotecid://80031049-E486-4FD3-9EC6-7B083434A989/appyinxiangcom/1518045/ENResource/p1012)]

二、编码&解码

Py2 Vs Py3编码

python生下来的时候 还没有unicode&utf-8, 所以龟叔选用的默认编码只能是ASCII, 一真到py2.7,用的还是ASCII, 导致Py默认只支持英文,想支持其它语言,必须单独配置。

直接写中文执行会报错的。
需在文件开头声明文件的编码才能写中文

再执行就不会有错了。
不过注意如果你的电脑 是windows系统 , 你的系统默认编码是GBK ,你声明的时候要声明成GBK, 不能是utf-8, 否则依然是乱码,因为gbk自然不认识utf-8.
在Py2里编码问题非常头疼,若不是彻底理解编码之间的各种关系,会经常容易出现乱码而不知所措。
到了Py3推出后,终于把默认编码改成了unicode, 同时文件存储编码变成了utf-8,意味着,不用任何声明,你就可以写各种语言文字在你的Python程序里。 从此,程序们手牵手过上了快乐的生活。

编码的转换

无论你以什么编码存储的数据,只要你的软件在把数据从硬盘读到内存里,转成unicode来显示,就可以了。由于所有的系统、编程语言都默认支持unicode,那你的gbk软件放到美国电脑上,加载到内存里,变成了unicode,中文就可以正常展示啦。

Python3的执行过程

在看实际代码的例子前,我们来聊聊,python3 执行代码的过程

  1. 解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode
  2. 把代码字符串按照语法规则进行解释
  3. 所有的变量字符都会以unicode编码声明

在这里插入图片描述

编码转换是指将一种编码转成另外一种编码,比如 utf-8 to gbk。
为何需要编码转换呢? 因为不同操作系统编码不同, utf-8在win上没办法直接看,因为windows是GBK编码的,得转成gbk。 反过来如果你的GBK字符相在Linux\Mac上正常显示,就得转成utf-8编码。
编码&解码

在这里插入图片描述

>>> s.encode("utf-8")   # 编码
b'\xe5\xb0\x8f\xe7\x8c\xbf\xe5\x9c\x88'
>>> s_utf8=s.encode("utf-8")
>>>
>>> s_utf8.decode("utf-8")  #解码
'小猿圈'

在py3里,内存里的字符串是以unicode编码的,unicode的其中一个特性就是跟
所有语言编码都有映射关系。所以你的utf-8格式的文件,在windows电脑上若是不能看,就可以把utf-8先解码成unicode,再由unicode编码成gbk就可以了。
在这里插入图片描述

注意,不管在Windows or Mac or Linux上,你的pycharm IDE都可以支持各种文件编码,所以即使是utf-8的文件,在windows下的pycharm里也可以正常显示

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值