那些年,我们一起经历过的乱码

 

那些年,我们一起经历过的乱码

 

俗话说:“知己知彼方能百战不殆”。要想了解字符编码,咱们还得从计算机编码说起!


 

*  ASCII*

话说,发明计算机的美国人没有想到计算机会在这短短几十年内普遍全球,且英文字符的个数十分有限,大小写字母,数字0 到9,标点符号,以及在美式英语中使用的特殊控制字符加起来也就百来个。而在计算机中一个字节相当于8个比特位,8个比特位就可以表示256(2的8次方)个字符,ASCII码规定用1个字节存储一个字符,简直妥妥的!


扩展字符集

然而计算机在普及到其他国家时,他们发现有很多他们的字母里有许多是ASCII里没有的,他们决定采用 127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128 到255这一页的字符集便是扩展字符集


GB2312

时代在进步,计算机普及到咱们中国来啦!但在普及的过程中我们面临的最大问题,不是买不买得起而是字符编码。因为华夏文明,博大精深,源远流长。常见的汉字就有成千上万个,这已经大大超过ASCII码所能存储的范围。于是我们制定了GB2312,不客气地把ASCII码127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,GB2312编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在127号以下的那些就叫”半角”字符了。基本满足了汉字的计算机处理需要


GBK

虽然GB2312所收录的汉字已经覆盖*99.75%的使用频率。但是并不是100%鸭!对于一些罕见的字和繁体字,GB2312还是无法处理的鸭!于是在GB2312的基础上创建了叫GBK的编码,不仅收录了27484个汉字,同时还收录了蒙文,藏文等主要的少数名族文字。同样GBK也兼容了ASCII编码,对于英文字符用1个字节来表示,汉字用俩个字节


Unicode

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。


utf-8

虽然unicode的出现使得乱码问题从此消失了。但是如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间

那些年的编码知识已上齐!不知各位看官是否看得很懵逼?懵逼,那就多看几遍!

接下来咱们该上大菜啦


python2

1,字符串的两大阵营:str和unicode

在python2.7中,有两种“字符串”类型,分别是str 与 unicode,他们有同一个基类basestring。str是plain string,其实应该称之为字节串,因为是每一个字节换一个单位长度。而unicode就是unicode string,这才是真正的字符串,一个字符(可能多个字节)算一个单位长度。

python2.7中,unicode类型需要在文本之间加u表示。

那些年,我们一起经历过的乱码

从上可以得出以下结论:第一s,c的类型是不一样的;第二,同一个汉字,不同的类型其长度也是不一样的,对于unicode类型的实例,其长度一定是字符的个数,而对于str类型的实例,其长度是字符对应的字节数目。

2,str与unicode的转换

unicode.encode--->str(编码)

str.decode---->unicode(解码)

3,指明的编码名称不对,抛出的报错还是熟悉的“配方”,熟悉的颜色!

那些年,我们一起经历过的乱码

我们来好好“观赏”图中 UnicodeEncodeError ,它分别展示了使用的编码方式, “codec” 即编码、解码器,导致问题的字符的位置。从中我们可以得出错误原因:“ascii 只能表示 0-127个 字符中的一个。然而我们的 字符串早已经超出了范围。”

偷偷告诉你哦其实我们可以通过设置encode 或者 decode 的第二个参数来指明codec 不能够处理数据的时候会发生的情况。通常第二参数的默认值是 “strict” ,就像刚才一样,会抛出一个异常。再者我们可以输入“replace” ,它意味着,失败时将会返回一个标准的替代字符。或者输入”ignore” ,它会直接将不能解码的 bytes 丢掉。

python3

1,字符串的俩大阵营:byte和str

跟 Python 2 类似,Python 3 也有两种类型,一个是 Unicode,一个是 byte 码。但是它们有不同的命名。python3你从普通文本转换成 “str” 类型后存储的是一个 unicode, “bytes” 类型存储的是 byte 串。你也可以通过一个 b 前缀来制造 byte 串。即py3中的str=py2中的unicode,py3中 的byte=py2中的str

2.byte与str的转换

在python3中str都是unicode,因此对于str只有encode(),没有decode(),而byte是由str使用encode()生成的,所以byte可以通过decode()即解码,得到真正的内容。

那些年,我们一起经历过的乱码

 

 

 

 

上一篇:Ubuntu 18.04下,Goland和Clion 不能输入中文问题;


下一篇:Mac安装Allure