#!/usr/bin/python3 # ============================================================== # hex dump # ============================================================== # -------------------------------------------------------------- # ---- display a chunk of bytes in hex and ASCII # ---- # ---- byte array chunk should 16 bytes or less # ---- # ---- byte array is a slice of the original array # ---- starting at the start index # -------------------------------------------------------------- def print_chunk(byt_ary,start_index): ln = len(byt_ary) print(f'{start_index:08} ',end='') for i in range(16): if i < ln: byt = byt_ary[i] print(f'{byt:02x} ',end='') else: print(' ',end='') for i in range(16): if i < ln: byt = byt_ary[i] if byt < 32 or byt > 126: # printable ASCII char? bchr = '.' else: bchr = chr(byt) else: bchr = ' ' print(bchr,end='') print() # -------------------------------------------------------------- # ---- print title # -------------------------------------------------------------- def print_hex_dump_title(): title = '-offset- ' +\ '--------------------- hex ---------------------' +\ ' ---- ascii -----' print(title) # -------------------------------------------------------------- # ---- hex_dump start index and length # ---- # ---- byt_ary byte array to hex dump # ---- start starting offset (index) to display # ---- length number of bytes to display # -------------------------------------------------------------- def hex_dump_length(byt_ary,start,length): if start < 0: return False if length < 1: return False end = start + length - 1 if end < start: return False return hex_dump(byt_ary,start,end) # -------------------------------------------------------------- # ---- hex_dump start/end index (inclusive) # ---- # ---- byt_ary byte array to hex dump # ---- start starting offset (index) to display # ---- end ending offset (index) to display # -------------------------------------------------------------- def hex_dump(byt_ary,start,end): byt_ary_len =len(byt_ary) # --- validate start,end array indexes if start > byt_ary_len - 1: start = byt_ary_len - 1 if end > byt_ary_len - 1: end = byt_ary_len - 1 if end < start: print(f'error: end < start {end} < {start}') return False # --- display hex dump chunks (16 bytes or less) print_hex_dump_title() while start <= end: print_chunk(byt_ary[start:end+1],start) start += 16 return True # -------------------------------------------------------------- # ---- main # -------------------------------------------------------------- if __name__ == '__main__': import user_interface as ui jpeg_file_path = 'mona_lisa_small_a.jpg' with open(jpeg_file_path,'rb') as file: jpeg_bytes = file.read() def test_start_end(): print() print(f'bytearray length = {len(jpeg_bytes)}') while True: # ---- test start/index print() s = ui.get_user_input('Enter start index: ') if not s: break tf,start = ui.is_integer(s) if tf is not True or start < 0: print(f'bad start index {s}') continue # ---- end index print() s = ui.get_user_input('Enter end index: ') if not s: break tf,end = ui.is_integer(s) if tf is not True or end < start: print(f'bad end index {s}') continue print() tf = hex_dump(jpeg_bytes,start,end) if tf is not True: print('OOPS!') def test_start_length(): print() print(f'bytearray length = {len(jpeg_bytes)}') while True: # ---- test start/length print() s = ui.get_user_input('Enter start index: ') if not s: break tf,start = ui.is_integer(s) if tf is not True or start < 0: print(f'bad start index {s}') continue # ---- length print() s = ui.get_user_input('Enter length: ') if not s: break tf,length = ui.is_integer(s) if tf is not True or length < 1: print(f'bad length {s}') continue print() tf = hex_dump_length(jpeg_bytes,start,length) if tf is not True: print('OOPS!') # ---- which test print() s = ui.get_user_input('Test end or length [end,len]: ') if not s: exit() if s[0] =='l' or s[0] == 'L': test_start_length() elif s[0] == 'e' or s[0] == 'E': test_start_end() else: print() print('bad_selection')