bytes.fromhex()和encode()之间的区别

时间:2017-12-09 09:29:23

标签: python python-3.x encoding

key = '140b41b22a29beb4061bda66b6747e14' # hex-encoded

>>> bytes.fromhex(key)
b'\x14\x0bA\xb2*)\xbe\xb4\x06\x1b\xdaf\xb6t~\x14'

这似乎是正确的,因为我为CBC(密码)编写的代码在此之后工作。

以下代码的灵感来自this site.

>>> "".join([chr(int(key[i:i+2],16)) for i in range(0,len(key),2)]).encode()
b'\x14\x0bA\xc2\xb2*)\xc2\xbe\xc2\xb4\x06\x1b\xc3\x9af\xc2\xb6t~\x14'

所以,我的问题是:为什么输出在两种情况下都不同,更重要的是在第二种情况下长度如何从16字节增加到21字节?

1 个答案:

答案 0 :(得分:1)

您将十六进制值的 text 表示形式编码为UTF-8(如果未指定,则为默认编码)。例如,B2十六进制值转换为Unicode代码点U + 00B2,其编码为UTF-8为C2 B2。

如果要为Unicode代码点匹配字节,则需要编码为Latin-1:

>>> "".join([chr(int(key[i:i+2],16)) for i in range(0,len(key),2)]).encode('latin1')
b'\x14\x0bA\xb2*)\xbe\xb4\x06\x1b\xdaf\xb6t~\x14'

Unicode的前256个代码点对应于Latin-1标准,因此U + 00B2以二进制形式直接编码为B2。

如果要将十六进制字节转换为整数,请不要创建Unicode文本。只需将整数直接传递给bytes

>>> bytes(int(key[i:i + 2], 16) for i in range(0, len(key), 2))
b'\x14\x0bA\xb2*)\xbe\xb4\x06\x1b\xdaf\xb6t~\x14'

这样您就不必从Unicode转换回字节。