首页 > 解决方案 > 创建列表值的十六进制转储

问题描述

我编写了一个显示来自通信线路的数据的模块。它应在十六进制转储中显示传输的数据。

如何将列表转换a=[0x41,0x42,0x43,0x0D]为十六进制转储,例如

41 42 43 0D      ABC.

请注意,不可打印的字符被替换为点。

我试过这个''.join(map(chr,a))。这在 Python shell 中显示为 'ABC\n',但这仍然包括换行符。

在另一种方法中,我想将列表完全按照 Python shell 中显示的方式显示到输出。即换行应显示为“\n”,而不是转到下一行。如何用点替换\n\\n替换任何其他不可打印的字符?

标签: pythonpython-3.x

解决方案


我假设您想将控制字符转换为点(ASCII 码低于 32 的字符)。

我还将假设字符渲染(第二部分)应该从一个固定的偏移量开始,这样当数据变得太宽时,您需要将数据拆分为多行。

代码:

def hexdump(data):
    return "\n".join(
        " ".join(["{:02X}".format(n) for n in chunk]).ljust(49) + 
        "".join([chr(n) if chr(n).isprintable() else "." for n in chunk])
        for chunk in [data[i:i+16] for i in range(0, len(data), 16)]
    )

示例运行:

a=[0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43
,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x41,0x42,0x43,0x0D]
print(hexdump(a))

输出:

41 42 43 41 42 43 41 42 43 41 42 43 41 42 43 41  ABCABCABCABCABCA
42 43 41 42 43 41 42 43 41 42 43 41 42 43 41 42  BCABCABCABCABCAB
43 0D                                            C.

转义控制字符

您在问题末尾询问的替代方法可以使用正则表达式或translate

trans = str.maketrans({ 
    i: "\\" + ("x{:02x}".format(i) if i < 7 or i > 13  
              else "abtnvfr"[i-7]) 
    for i in range(32)
})

s = "first line\nsecond line\r\ncol1\tcol2\nspecial \x1f"
print(s)
print(s.translate(trans))

\x01这将使用符号转义控制字符(在 ASCII 范围内 0 - 31 中) ,或者在存在这样的助记符时使用\n, \r,...。


推荐阅读