Skip to content

Instantly share code, notes, and snippets.

@texadactyl
Last active June 11, 2018 16:56
Show Gist options
  • Save texadactyl/ac1e106aca9a5faeefea87072f8a182d to your computer and use it in GitHub Desktop.
Save texadactyl/ac1e106aca9a5faeefea87072f8a182d to your computer and use it in GitHub Desktop.
For a given Python object, create a labeled dump with hex on the left and ASCII on the right.
"""
Cheap-o-cigar hexdump, somewhat cribbed from somewhere that I cannot recall.
2018-06-10 texadactyl Version 1
"""
import struct
def _bytes2ints(arg_bytes):
ilist = []
for i in range(0, len(arg_bytes)):
ilist.append(int(arg_bytes[i]))
return ilist
def _printable(arg_int):
if arg_int > 31 and arg_int < 127:
return chr(arg_int)
return '.'
def execute(arg_label, arg_data, arg_line_size):
"""
Dump hex portion on the lect, displayable portion on the right.
Non-printable characters are replaced with a '.' in the displayable portion.
arg_label: first line.
arg_data: blob to dump.
arg_line_size = number of characters dumped per line.
Result returned is a string of the form: "label\nline1\nline2\netc.\n".
Sample invocation:
>>>print(hexdump.execute("100 ASCII zeroes:", b'0' * 100, 16))
100 ASCII zeroes:
0000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0010 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0020 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0030 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0040 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0050 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
0060 30 30 30 30 0000
"""
byte_array = bytearray(arg_data)
cookedlines = [arg_label]
fmt = "%%04X %%-%ds %%s" % (3 * arg_line_size - 1,)
fmtlinesize = 7 + 3*arg_line_size + 3 + arg_line_size
for i in range(0, len(byte_array), arg_line_size):
line = byte_array[i:i+arg_line_size]
intlist = _bytes2ints(line)
hextext = " ".join('%02x' % b for b in intlist)
rawtext = "".join(_printable(b) for b in intlist)
cookedlines.append(fmt % (i, str(hextext), str(rawtext)))
if cookedlines:
cookedlines[-1] = cookedlines[-1].ljust(fmtlinesize)
cookedlines.append("")
return "\n".join(cookedlines)
if __name__ == "__main__":
DATA = b'\x21\x22'
print(execute("Bytes 0x21 and 0x22:", DATA, 16))
print(execute("Integer 42:", struct.pack('i', 42), 16))
print(execute("Double-precision Pi:", struct.pack('d', 3.14159265), 16))
print(execute("Alphabet:", "ABCDEFGHIJKLMNOPQRSTUVWXYZ".encode(), 16))
print(execute("100 ASCII zeroes:", b'0' * 100, 16))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment