创建列表值的十六进制转储

har*_*per 0 python python-3.x

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

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

41 42 43 0D      ABC.
Run Code Online (Sandbox Code Playgroud)

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

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

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

tri*_*cot 5

我假设您想将控制字符转换为点(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)]
    )
Run Code Online (Sandbox Code Playgroud)

示例运行:

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))
Run Code Online (Sandbox Code Playgroud)

输出:

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)]
    )
Run Code Online (Sandbox Code Playgroud)

转义控制字符

您在问题末尾询问的替代方案可以使用正则表达式或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))
Run Code Online (Sandbox Code Playgroud)

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