在十六进制字节和字符串之间转换

0 投票
2 回答
57 浏览
提问于 2025-04-14 16:49

我相信这个问题的解决办法很简单,但我在网上找不到答案。可能是我搜索的方法不对。

我想在Python中方便地在字符和它的二进制、十六进制表示之间切换。通常我这样做:

如果我有一个字符,比如说 chr(97),也就是字母 "a",我可以通过以下方式得到它的二进制表示:

byte_character=chr(97).encode()

或者得到它的十六进制表示:

hex_character=chr(97).encode().hex()

如果我想把它们转换回去,可以使用:

bytes.fromhex(hex_character).decode()

byte_character.decode()

这样对大多数字符都能正常工作,但有些字符的编码会用到多个字节。例如,chr(140)编码后会变成两个字节:

chr(140).encode()

结果是:

b'\xc2\x8c'

而不是我预期的 b'\x8c'。你能告诉我我哪里做错了吗?

2 个回答

2

UTF-8是一种编码方式,通常是默认使用的,除非你特别指定其他的编码。它会把任何大于128(也就是0x7F)的Unicode字符用两个或更多字节来表示。所以当你用chr(x)得到的结果大于128时,它会返回两个或更多的字节。

要解决这个问题,有两种方法。

第一种是使用'latin1'编码,这样可以让它在0到255的范围内返回1个字节。

x = chr(140)
byte = x.encode('latin1')
print(x)
>>> b'\x8c'

第二种方法是Python有一个内置函数叫to_bytes。使用这个方法时,不需要提前转换数字。你还可以在第一个参数中指定想要返回的字节数。

x = 140
byte = x.to_bytes(1, 'little')
print(byte)
>>> b'\x8c'

这两种方法都可以很好地解决你想要实现的功能。

3

如果你只需要处理0到255这个范围的字节,可以使用latin1编码,也叫做ISO-8859-1编码。

>>> chr(140).encode('latin1')
b'\x8c'
>>> chr(255).encode('latin1')
b'\xff'
>>> chr(256).encode('latin1')
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0100' in position 0: ordinal not in range(256)

你之前的尝试是默认使用UTF-8编码,这种编码对于127以上的字符会使用多个字节来表示。

>>> chr(140).encode()
b'\xc2\x8c'
>>> chr(127).encode()
b'\7f'
>>> chr(128).encode()
b'\xc2\x80'
>>> chr(12345).encode()
b'\xe3\x80\xb9'

撰写回答