在python中如何将带不可打印字符的字节串转换成十六进制?

2024-05-16 04:16:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个ANSI字符串Ď–ór˙rXüď\ő‡íQl7,我需要像这样将它转换成十六进制: 06cf96f30a7258fcef5cf587ed51156c37(用XVI32转换)。在

问题是Python不能正确地编码所有字符(有些字符甚至在这里显示错误,堆栈溢出时),所以我不得不用字节字符串来处理它们。在

所以上面的字符串以字节为单位:b'\x06\xcf\x96\xf3\nr\x83\xffrX\xfc\xef\\\xf5\x87\xedQ\x15l7'

这就是我需要转换成十六进制的。在

到目前为止,我试过比纳西,但没有成功,我试过:

h = ""
for i in b'\x06\xcf\x96\xf3\nr\x83\xffrX\xfc\xef\\\xf5\x87\xedQ\x15l7':
    h += hex(i)
print(h)

它打印:

0x60xcf0x960xf30xa0x720x830xff0x720x580xfc0xef0x5c0xf50x870xed0x510x150x6c0x37

好吧。看来我要去某个地方了。。。但是这是怎么回事?在

当我像这样从字符串中删除0x时:

^{pr2}$

我得到了6cf96f3a7283ff7258fcef5cf587ed51156c37,看起来是正确的。在

但有时字节串在x旁边有一个0,它会从字符串中删除,从而导致一个不正确的十六进制字符串。(上面的字符串缺少开头的0)。在

有什么想法吗?在


Tags: 字符串字节字符nrxcfxefxf5x83
2条回答

根据文档,^{}“一个整数转换为前缀为'0x'”的小写十六进制字符串,因此当使用hex()时,总是会得到一个0x前缀。如果您想连接多个十六进制表示,则必须删除它。在

But sometimes the byte string has a 0 next to a x and it gets removed from the string resulting in a incorrect hexadecimal string. (the string above is missing the 0 at the beginning).

那没有任何意义。x不是有效的十六进制字符,因此在您的解决方案中,它只能由hex()调用生成。如上所述,这将始终创建一个0x。因此序列0x在结果字符串中不会以不同的方式出现,因此用任何内容替换{}应该可以很好地工作。在

您的解决方案中的实际问题是hex()没有执行两位数的结果,如下面的示例所示:

>>> hex(10)
'0xa'
>>> hex(2)
'0x2'

所以在您的例子中,由于字符串以b\x06开头,它代表数字6hex(6)只返回{},所以这里只得到一个数字,这才是问题的真正原因。在


您可以使用格式字符串执行到十六进制的转换。这样,你就可以省去前缀,并强制使用两位数的长度。然后您可以使用str.join将其组合成一个十六进制字符串:

^{pr2}$

此解决方案不仅适用于字节字符串,而且适用于任何可以格式化为十六进制字符串(例如整数列表)的内容:

>>> value = [1, 2, 3, 4]
>>> ''.join(['{:02x}'.format(x) for x in value])
'01020304'

如果您运行的是python3.5+,bytes类型有一个新的^{}方法,该方法返回字符串表示。在

>>> h = b'\x06\xcf\x96\xf3\nr\x83\xffrX\xfc\xef\\\xf5\x87\xedQ\x15l7'
b'\x06\xcf\x96\xf3\nr\x83\xffrX\xfc\xef\\\xf5\x87\xedQ\x15l7'
>>> h.hex()
'06cf96f30a7283ff7258fcef5cf587ed51156c37'

否则,您可以使用^{}来执行相同的操作

^{pr2}$

相关问题 更多 >