HOWTO · Python
在 Python 中将字符串转换为十六进制
本教程演示了如何在 Python 中将字符串转换为十六进制
本页内容
Python 字符串表示文本;十六进制输出可以表示编码生成的字节,也可以表示每个字符的 Unicode 码点。若要得到可移植的字节表示,请先选择编码,调用 encode(),再用 bytes.hex() 转换这些字节。若结果需要在不同系统间保留非 ASCII 文本,UTF-8 是常见选择。
下面的示例对同一段文本分别展示 UTF-8 字节的十六进制形式和码点的十六进制形式。对于此输入,它会依次显示连续的 UTF-8 字节十六进制值、以空格分组的字节值,以及未补齐位数的码点值。示例中的标签和输出行保持英文;下文会说明它们各自表示什么。
使用 encode() 和 hex() 将 Python 字符串转换为十六进制
str.encode() 使用指定的编码将文本转换为字节。随后,字节对象的 hex() 方法会为每个字节返回两位十六进制数字。编码方式会影响结果:例如,é 在 UTF-8 中会编码为两个字节,因此其字节的十六进制值是 c3a9,而它的码点是 e9。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
text = "Café"
encoded = text.encode("utf-8")
print(encoded.hex())
print(encoded.hex(" "))
print("".join(hex(ord(character))[2:] for character in text))
436166c3a9
43 61 66 c3 a9
436166e9
第一行是连续的 UTF-8 字节十六进制值;第二行在每个字节之间加空格,便于阅读。第三行显示的是码点,因此含义不同。需要标准的连续十六进制字符串时,请使用不分组的形式;分隔符便于查看,但也会成为返回字符串的一部分。示例中的标签和输出保持英文。
使用 binascii.hexlify() 作为替代方法
标准库函数 binascii.hexlify() 也可以将字节转换为表示十六进制的字节。先对字符串进行编码;如果后续步骤需要 Python 文本字符串,再解码转换结果:
本节中的代码以及显示的标签或输出仍为英文。
import binascii
text = "Café"
hex_text = binascii.hexlify(text.encode("utf-8")).decode("ascii")
hex_text 的值是 436166c3a9。
解码前,返回值是一个包含 ASCII 字符的 bytes 对象,例如 b'436166c3a9'。无论原始文本采用什么编码,都可以用 ASCII 解码,因为十六进制数字属于 ASCII 字符。若某个 API 明确要求使用 binascii 或要求字节输出,这种方法就很实用;若只需要普通文本输出,bytes.hex() 更简洁。
使用 ord() 和 hex() 转换字符码点
若要表示每个字符的 Unicode 码点,而不是其编码后的字节,可对每个字符调用 ord(),再将得到的整数传给 hex()。如果只需要数字本身,可以去掉 0x 前缀。这与 UTF-8 表示法不同:é 的码点是 e9,而它的 UTF-8 字节是 c3 a9。
拼接码点的十六进制数字时,位数不固定可能导致边界不清。例如,码点 0x41 和 0x1f600 在不加分隔符时会变成 411f600,无法看出一个值在哪里结束、下一个值从哪里开始。如果其他程序需要解析各个码点,请保留分隔符或使用固定宽度补齐。
如何选择编码后的字节或字符码点
如果需要的是按特定编码存储、传输或比较的字节,请使用 text.encode(encoding).hex()。只有在明确需要 Unicode 码点时,才使用 ord() 方法;它不会生成编码后的字节序列。
Python 内置的 hex() 接受整数,不接受字符串。直接将文本传给它会引发 TypeError。使用 int(value, 16) 转换已经包含十六进制数字的数值字符串,是另一项解析任务,并不能用来编码任意文本。通常,要将字符串转换为十六进制,请指定编码,然后依次使用 encode() 和 hex()。