class Hexdumper: def naive_hexdump(s): b = 0 for c in s: print(f"{ord(c):<0x}") b += 1 if b >= 15: print("\n") def read_chunk(byte_array, chunk_size=16): for i in range(0, len(byte_array), chunk_size): yield byte_array[i:i + chunk_size] def hexdump(s): b = 0 bytes = s.encode("UTF-8") for linebytes in Hexdumper.read_chunk(bytes): # Print byte offset (column 1) print(f"{b:>08x} ", end='') # Print hex bytes (column 2) for c in linebytes: print(f"{c:0x} ", end='') b += 1 # Add padding to get to column 3 if we haven't printed 16 hex bytes if b % 16 != 0: print(" " * (48-((b % 16)*3)), end='') # Print characters (column 4) for c in linebytes: if c > 32 and c <= 127: print(f"{chr(c)}", end='') else: print("?", end='') print("") if __name__ == "__main__": Hexdumper.hexdump("🐶🐮✅🌭🐱🐶🐮✅🌭🌭🌭🌭") Hexdumper.hexdump("abcdef[]093840.: )@#u,p03UX)")