python 编码为 utf-8 时随机添加字节到字符串
python randomly adds bytes to a string when encoding to utf-8
我正在尝试编写一个函数,该函数接受小数并将其以相反的顺序转换为十六进制转义序列。我编写的代码适用于大多数数字,如示例中的代码,但随机地,它在开头添加了一个额外的字节 \xC2 或 \xC3 。我假设这是因为 utf-8 的工作方式特殊,但需要它恰好有 4 个字节。从测试来看,它似乎每隔 128 个数字发生一次,它从 section
的半点开始切换到 \xC3
我可以系统地删除添加的额外字节,但这似乎是随机的,必须有更好的方法来做到这一点那么这个随机额外字节背后的原因是什么以及我如何防止它发生, 或者我应该系统地删除它
下面是我写的函数:
def convert_int_to_reverse_hex_escape_sequence(decimal):
# example of the variable in comments # decimal = 275
hexadecimal = hex(decimal) # 0x113
padded = hexadecimal[2:].zfill(8) # 00000113
array = re.findall('..', padded) # ['00', '00', '01', '13']
array.reverse() # ['13', '01', '00', '00']
unicode = ''.join([chr(int(x, 16)) for x in array]).encode('utf-8') # b'\x13\x01\x00\x00'
return unicode
UTF-8 将任何 Unicode 代码点 >128 (0x7F) 编码为两个或更多字节,因此当 chr(x,16)
的结果 >128 时,您将看到您的问题:
>>> ''.join(chr(int(x,16)) for x in ['80','90','A0','B0']).encode('utf8')
b'\xc2\x80\xc2\x90\xc2\xa0\xc2\xb0'
latin1
会做你想做的,因为它在 1:1 的基础上将字符 0-255 转换为字节 0-255:
>>> ''.join(chr(int(x,16)) for x in ['80','90','A0','B0']).encode('latin1')
b'\x80\x90\xa0\xb0'
但是您的用例有一个内置函数。告诉它你想要多少字节和小端或大端:
>>> x = 275
>>> x.to_bytes(4,'little')
b'\x13\x01\x00\x00'
我正在尝试编写一个函数,该函数接受小数并将其以相反的顺序转换为十六进制转义序列。我编写的代码适用于大多数数字,如示例中的代码,但随机地,它在开头添加了一个额外的字节 \xC2 或 \xC3 。我假设这是因为 utf-8 的工作方式特殊,但需要它恰好有 4 个字节。从测试来看,它似乎每隔 128 个数字发生一次,它从 section
的半点开始切换到 \xC3我可以系统地删除添加的额外字节,但这似乎是随机的,必须有更好的方法来做到这一点那么这个随机额外字节背后的原因是什么以及我如何防止它发生, 或者我应该系统地删除它
下面是我写的函数:
def convert_int_to_reverse_hex_escape_sequence(decimal):
# example of the variable in comments # decimal = 275
hexadecimal = hex(decimal) # 0x113
padded = hexadecimal[2:].zfill(8) # 00000113
array = re.findall('..', padded) # ['00', '00', '01', '13']
array.reverse() # ['13', '01', '00', '00']
unicode = ''.join([chr(int(x, 16)) for x in array]).encode('utf-8') # b'\x13\x01\x00\x00'
return unicode
UTF-8 将任何 Unicode 代码点 >128 (0x7F) 编码为两个或更多字节,因此当 chr(x,16)
的结果 >128 时,您将看到您的问题:
>>> ''.join(chr(int(x,16)) for x in ['80','90','A0','B0']).encode('utf8')
b'\xc2\x80\xc2\x90\xc2\xa0\xc2\xb0'
latin1
会做你想做的,因为它在 1:1 的基础上将字符 0-255 转换为字节 0-255:
>>> ''.join(chr(int(x,16)) for x in ['80','90','A0','B0']).encode('latin1')
b'\x80\x90\xa0\xb0'
但是您的用例有一个内置函数。告诉它你想要多少字节和小端或大端:
>>> x = 275
>>> x.to_bytes(4,'little')
b'\x13\x01\x00\x00'