Last active
June 11, 2018 16:56
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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