From 0a54213e0dce38e823de83ac6284be0c00270b29 Mon Sep 17 00:00:00 2001 From: Martinez Date: Tue, 11 Aug 2015 21:05:44 +0200 Subject: [PATCH] add over.core.misc.hexdump --- core/misc.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/core/misc.py b/core/misc.py index 80edd83..3955da5 100644 --- a/core/misc.py +++ b/core/misc.py @@ -3,7 +3,9 @@ import copy import imp +import math import os +import sys # -------------------------------------------------- @@ -82,3 +84,53 @@ def debugger(): import pdb pdb.set_trace() + +# -------------------------------------------------- + +def hexdump(data, indent=0, offset=16, show_offsets=True, show_ascii=True, output=sys.stdout): + """ + Writes a hex dump of 'data' to 'output'. + + The output text is indented with spaces and contains 'offset' bytes per line. + If show_offsets is True, each line is prefixed with the address of the first byte of that line. + If show_ascii is True, each line is suffixed with its ASCII representation. Unprintable characters + are replaced with a dot. + The 'output' must implement a .write(str) method. + """ + + if type(data) is not bytes: + raise ValueError('data must be bytes') + + format_str = '%%0%dx ' %(math.ceil(math.log2(len(data)) / 8) * 2) + ptr = 0 + + while data[ptr:]: + if indent: + output.write(' ' * indent) + + if show_offsets: + output.write(format_str %(ptr)) + + hex_bytes = [] + ascii_bytes = [] + + for local_i, i in enumerate(range(ptr, ptr+offset)): + if i < len(data): + c = data[i] + hex_bytes.append('%02x' %(c)) + + if 0x20 <= c <= 0x7e: + ascii_bytes.append(chr(c)) + else: + ascii_bytes.append('.') + elif i == len(data): + hex_bytes.extend([' '] * (offset - local_i)) + + output.write(' '.join(hex_bytes)) + + if show_ascii: + output.write(' ' + ''.join(ascii_bytes)) + + output.write('\n') + + ptr += offset