python 字符的编码

参考 廖雪峰-字符串和编码
https://blog.csdn.net/weixin_41789688/article/details/116787795
Unicode编码详解(一):Unicode简介及其分类

首先计算机内部只能识别数字,在底层就是0,1编码。比如:不论是数字100,还是字符 今天,在底层都是1010 1000 1010 这种形式的二进制代码

二进制:
二进制只有0,1两种状态,所以只需要一个二进制位(也就是一个比特位)就可以表示二进制数。
在这里插入图片描述

八进制:
八进制有八种状态:0,1,2,3,4,5,6,7
八种状态需要三个比特位才能表示 000–111
所以一个八进制数占了三个比特,比如 7 表示出来就是三个比特位111才能表示
在这里插入图片描述

十六进制:
十六进制有16种状态: 0-9,A-F
十六中状态可以用四个比特位表示 0000-1111。
所以一个十六进制数,对应着4个比特位。

假设汉字一共只有16种,我们让每一个汉字对应着一个数字(0-15),用十六进制表示就是
在这里插入图片描述
这些十六进制数,在计算机内可以用比特位来表示出来,所以这样中文的文本就可以在计算机中表示了。
在这里插入图片描述
所以 天气真好 在计算机中就表示成了 1111 1010 0100 0010

基于这种想法,由于计算机是美国人发明的,所以他们也想让计算机可以表示出他们的语言。对于英语来说,26个大写字母,26个小写字母,10个数字,加上其他的一些符号,他们一共就127个字符,所以他们建立了一个对应关系:
在这里插入图片描述
这就是ascii码表,一共128个字符,使用一个字节(xxxx xxxx)就可以完全表示这些字符。一个字节能表示的最大的整数就是255(二进制11111111=十进制255),就是255种状态,表示128种状态肯定是够了。

汉语中有那么多个汉字,算上各种繁体字,大概几万个吧,这些字符仅仅使用一个字节是不够的。比如两个字节可以表示的最大整数是65535。

但是现在这么多国家都在使用计算机,不同国家字符不同,所以不同的国家又自己制定了自己需要的一张表。

假如说现在用两个字节(0—65535)来表示这些字符。除去一些通用的字符(数字,符号之类的),然后不同的国家需要不同的字符对应关系,比如:
在汉语中, 21234 —> 编
日语中,21234 —> xx(反正是其他的字符)
那么同样的一段编码,在不同的计算机中,解码出的语言就完全不一样了,这样肯定是不行的。

Unicode

因此,Unicode字符集应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

可以简单理解为Unicode字符集是一个非常大的表,包括了全世界的字符,它给出了一个统一的规定,比如,哪个字符用哪个数表示,全球统一,这样就不存在乱码了。

Unicode为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),有110多万,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制,在前面加上U+。例如:“马”的Unicode是U+9A6C。

实际上每个字符都有一个10进制的整数来对应,这样方便我们人类来看,然后在Unicode字符集中,我们又给了它们另一个编号,这个编号是从0x000000 到 0x10FFFF(十六进制),所以每个字符对应一个10进制整数,同时也对应一个Unicode编号:U+xxxxxx形式

下面这里U+4E24,可以看出形式U+xxxxxx不是这种,我的理解是,这些字符是常用字符,位于第0个平面。前面两位直接省略了:

Unicode编码详解(一):Unicode简介及其分类
这个博文写得很详细
在这里插入图片描述

Unicode本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。

既然是十六进制,编号范围从 0x000000 到 0x10FFFF(十六进制),那么直接用这些编号对应的二进制存储也是可以的。
但是问题就是,这里有6个十六进制位,也就是24个比特位(3个字节),编码方式是比较简单,但是浪费空间啊,比如有个字符:
在这里插入图片描述
实际上a对应的十六进制0x000061对应的二进制完全不需要那么多位来表示
110 0001 就可以表示了,前面那么多字节就浪费了。

然后就有了变长编码:
针对不同范围的码点,不同范围意思是每个字符对应的整数编号,或者说Unicode编号(U+xxxxxx),不同区间内使用不同长度的字节。

使用不同长度的字节序列来表示 utf-8就是一种变长编码。

在这里插入图片描述

UTF-8使用1~4字节为每个字符编码:

  • 一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000~U+007F)。
  • 带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。
  • 其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。
  • 其他极少使用的语言字符使用4字节编码。

还有很多细节没有看,先简单了解一下。

Unicode字符集可以简写为UCS(Unicode Character Set)。就是一个字符集,一个大表格,有一个对应关系。

UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。就是怎么把这些字符对应的十六进制编码,按照哪种格式编码。

python中的字符串

再结合廖雪峰的例子,仔细理解一下:

首先,
Python对bytes类型的数据用带b前缀的单引号或双引号表示:
在这里插入图片描述
要注意区分'ABC'b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节。

纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

在bytes中,无法显示为ASCII字符的字节,用\x##显示:

由于在utf-8编码格式中,中文字符用3个字节编码,所以'今天天气真好'一共使用了18个字节。
在这里插入图片描述

如果我们想知道某一个字符在Unicode字符集中,对应的那个10进制整数是多少,我们可以使用ord()函数。

比如看一个中文字符
在这里插入图片描述
python中输出对应的Unicode整数编号
在这里插入图片描述
使用str.encode()方法把它按照utf-8编码格式编码:
在这里插入图片描述
可以看到和我们在Unicode官网查到的一样。

同时还可以发现:
在这里插入图片描述
‘\u4e2d’也对对应着'中',原来‘\u4e2d’是他的utf-16的编码形式。
其实十六进制4e2d对应的二进制是0100 1110 0010 1101 对应的整数是
20013,也就是他的整数编号

实际上在对’中‘进行utf-8编码是,就是先拿到他的整数编号20013,对应的二进制是
100 1110 0010 1101 ,根据编码规则,20013,在下面这个范围内,所以使用3个字节编码,编码有部分固定格式。

首先拿出20013对应的二进制100 1110 0010 1101,从最后以为开始,从右往左,把数字填到1110xxxx 10xxxxxx 10xxxxxx 中的x
在这里插入图片描述

在这里插入图片描述
没填满的补0

就变成了11100100 10111000 10101101 对应的十六进制为
在这里插入图片描述
也就是:
在这里插入图片描述

同时使用str.decode()将字节流解码成字符串
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值