_printable = dict((chr(i), ".") for i in range(256)) | |
_printable.update((chr(i), chr(i)) for i in range(32, 128)) | |
def hexdump(data, linesize = 16): | |
prettylines = [] | |
if len(data) < 65536: | |
fmt = "%%04X %%-%ds %%s" | |
else: | |
fmt = "%%08X %%-%ds %%s" | |
fmt = fmt % (3 * linesize - 1,) | |
for i in xrange(0, len(data), linesize): | |
line = data[i : i + linesize] | |
hextext = " ".join(b.encode("hex") for b in line) | |
rawtext = "".join(_printable[b] for b in line) | |
prettylines.append(fmt % (i, hextext, rawtext)) | |
return prettylines | |
class HexString(str): | |
""" | |
represents a string that will be hex-dumped (only via __pretty_str__). | |
this class derives of str, and behaves just like a normal string in all | |
other contexts. | |
""" | |
def __init__(self, data, linesize = 16): | |
str.__init__(self, data) | |
self.linesize = linesize | |
def __new__(cls, data, *args, **kwargs): | |
return str.__new__(cls, data) | |
def __pretty_str__(self, nesting = 1, indentation = " "): | |
sep = "\n" + indentation * nesting | |
return sep + sep.join(hexdump(self)) | |