当前位置: 首页 > 科技观察

三人一组还是四人一组?Bytes到Unicode的字节划分方法

时间:2023-03-15 00:51:32 科技观察

在Python开发过程中,经常会把字符串编码成Bytes数据,或者将Bytes数据解码成字符串。例如:我们知道在图片中,中文在Unicode编码中占3个字节,所以一个汉字编码为Bytes数据后,会占用3个Bytes的字符,例如:>>>a='qing'>>>a.encode()b'\xe9\x9d\x92'>>>b='清南'>>>b.encode()b'\xe9\x9d\x92\xe5\x8d\x97'注意\xe9需要作为一个整体,它代表一个十六进制数。所以,当我想把Bytes数据\xe9\x9d\x92\xe5\x8d\x97转成字符串时,Python会把\xe9\x9d\x92转成蓝色字符,把\xe5\x8d\x97转成Nanzi,Python似乎知道每3个字节的符号应该分组处理。但是在Unicode中,emoji表情是4个字节,比如emoji:??,它对应的Bytes数据是:\xf0\x9f\xa4\x94,如下图:是Bytes类型的数据,取值为:\xe9\x9d\x92\xf0\x9f\xa4\x94\xe5\x8d\x97,如下图,一共10个Bytes字符:那么问题来了,当我解码类型数据时会发生什么?如下图所示:Python可以将Bytes数据正确划分为:\xe9\x9d\x92对应“绿色”\xf0\x9f\xa4\x94对应“🤔”\xe5\x8d\x97对应《南》为什么Python知道把\xf0\x9f\xa4\x94这4个符号分到一组?为什么不像下面这样分组呢?\xe9\x9d\x92\xf0\x9f\xa4\x94\xe5\x8d\x97其实这个问题的原因只有我们用二进制来看才能找到。绿色对应第一个Bytes字符\xe9,其中e9为十六进制数,转十进制为233,转二进制为11101001。Nan对应第一个Bytes字符\xe5,其中e5为十六进制数,转转十进制为229,转二进制为11100101。??对应第一个Bytes字符\xf0,其中f0为十六进制数,转十进制为240,转二进制为11110000。如果还可以看不出区别,让我们一起比较一下:111010011110010111110000你看出区别了吗?汉字是三个字节。转换成Bytes数据后,第一个字符对应的二进制数是1110开头。表情符号是4个字节。转换成Bytes数据后,第一个字符对应的二进制数是从1111开始的。因此,当一个Bytes类型的数据需要Python转换成字符串时,Python会判断一组应该有多少个字符。给定Bytes类型的数据:\xe9\x9d\x92\xf0\x9f\xa4\x94\xe5\x8d\x97看第一个字符对应的二进制数的高4位是1110,所以当前字符和两个下面的字符对一组字符(共3个字符)进行分析,得到一个绿色字符。跳过解析出的字符,直接进入第四个\??xf0,发现其对应二进制数的高4位是1111,所以这个字符和后面3个字符(共4个字符)是一组,解析出来??.跳过解析的字符,来到第8位\xe5,对应的二进制高4位为1110,所以这个字符和后面两个字符一起解析得到Nan。结束。对于数字和英文字母,在Unicode中只用一个字节表示,Ascii码小于128。多字节Unicode字符都是129开头的,所以英文字母和数字与中文混合生成的Bytes型数据不会出现解码时分组不清晰的问题。本文转载自微信公众号“闻所未闻的密码”,可通过以下二维码关注。转载本文请联系Code公众号。