I'm trying to print a list of bytes to a file in hex (or decimal, doesn't really make a difference for the sake of the question I believe). I'm baffled by how hard this appears to be in Python?
Based on what I found here (and on other SO questions), I already managed to do this:
>>> b
[12345, 6789, 7643, 1, 2]
>>> ' '.join(format(v, '02x') for v in b)
'3039 1a85 1ddb 01 02'
Now... this is already a good start, but... for larger numbers the individual bytes are grouped and attached to each other. This should not happen. There should be a space between them, just like is the case with the two last numbers.
Of course, I could just do some string manipulation afterwards and insert some spaces, but... that sounds like a very hacky way, and I refuse to believe there isn't a cleaner way to do this.
So, what I want is this:
'30 39 1a 85 1d db 00 01 00 02'
How can I do this?
So, you want to create a hexdump-like output. Given your example inputs/outputs, it sounds like you want the big-endian, 16-bit length bytes from the integers in your list. The key is to use int.to_bytes
. Here is a function that first creates a list of bytes from the integers, then iterates over the individual bytes, formatting them as requested:
def hexdump(
data: list[int], length=2, byteorder: str = "big", fmt: str = "02x", sep: str = " "
) -> str:
bytes_data = (i.to_bytes(length=length, byteorder=byteorder) for i in data)
return sep.join([f"{b:{fmt}}" for bs in bytes_data for b in bs])
Here are some examples of it in use:
In [2]: data = [12345, 6789, 7643, 1, 2]
In [3]: hexdump(data)
Out[3]: '30 39 1a 85 1d db 00 01 00 02'
In [4]: hexdump(data, length=4, fmt='04x')
Out[4]: '0000 0000 0030 0039 0000 0000 001a 0085 0000 0000 001d 00db 0000 0000 0000 0001 0000 0000 0000 0002'
In [5]: hexdump(data, sep="|")
Out[5]: '30|39|1a|85|1d|db|00|01|00|02'