Access/Create Packed Binary Data

Table Of Contents

Read a File as Bytes

# --------------------------------------------------------------- # ---- open file and read it directly into a bytearray # ---- # ---- It is not necessary to read in the complete file # ---- if you are only accessing the headers. For example, # ---- read the first 1000 bytes? # ---- # ---- def load_file_to_array(file_path): # ---- f = open(file_path,'rb') # ---- byts = f.read(1000) # ---- close(f) # ---- return byts # ---- # ---- or # ---- # ---- def load_file_to_array(file_path): # ---- with open(file_path,'rb') as f: # ---- byts = f.read(1000) # ---- return byts # ---- # --------------------------------------------------------------- def load_file_to_array(file_path:str) -> bytearray: with open(file_path,'rb') as file: file_bytes = file.read() return file_bytes byts = load_file_into_array(file_path:str) print(type(byts))

Convert Bytes To an Integer

# --------------------------------------------------------------- # ---- each color is a single byte (0-255) # ---- (data slice is exclusive) # --------------------------------------------------------------- red_intensity = int.from_bytes(bmp_bytes[55:56],'little') green_intensity = int.from_bytes(bmp_bytes[56:57],'little') blue_intensity = int.from_bytes(bmp_bytes[57:58],'little') print(type(red_intensity)) print(type(green_intensity)) print(type(blue_intensity))

Convert Integer To Bytes

# --------------------------------------------------------------- # ---- each integer can be several bytes # ---- (data slice is exclusive) # --------------------------------------------------------------- byts1 = int.to_bytes(num,'big',signed=True) byts2 = int.to_bytes(num,'little') # default signed is False print(type(byts1)) print(type(byts2))

Convert Byte To an ASCII Character

# --------------------------------------------------------------- # ---- each byte is an ASCII character # ---- (data slice is exclusive) # --------------------------------------------------------------- char1 = chr(int.from_bytes(bmp_bytes[0:1],'little')) char2 = chr(int.from_bytes(bmp_bytes[1:2],'little')) print(type(char1)) print(type(char2))

Test Float Pack and Unpack

# --------------------------------------------------------------- # ---- test/display struct float packing and unpacking # # Note: the Python struct modules 'f' and 'd' conversion codes # uses the packed representation IEEE 754, binary32 # (for 'f') or binary64 (for 'd') format, regardless # of the floating-point format used by the platform # --------------------------------------------------------------- import struct from my_hex_dump import hex_dump import user_interface as ui # --------------------------------------------------------------- # ---- create a string from a byte array # --------------------------------------------------------------- def my_byte_string(byts:bytes) -> None: lst = [] for b in byts: lst.append('\\x' + f'{b:02X} ') return ''.join(lst) # --------------------------------------------------------------- # ---- process user input # --------------------------------------------------------------- def test_struct_float_pack_unpack(): while True: print() s = ui.get_user_input('Enter a float: ') if not s: break tf,flt = ui.is_float(s) if tf is not True: print('OOPS! Try again!') continue print() pflt = struct.pack('f', flt) # pack float print(f'flt type = {type(flt)}') print(f'pflt type = {type(pflt)}') print(f'pflt len = {len(pflt)}') ##print(f'pflt = {pflt}') print(f'pflt = {my_byte_string(pflt)}') ##hex_dump(pflt,0,len(pflt)-1) print() [xflt] = struct.unpack('f', pflt) # unpack float print(f'xflt type = {type(xflt)}') print(f'xflt = {xflt}') sflt = str(xflt) print(f'sflt type = {type(sflt)}') print(f'sflt = {sflt}') # --------------------------------------------------------------- # ---- main # --------------------------------------------------------------- test_struct_float_pack_unpack()

Convert Bytes to String

# --------------------------------------------------------------- # ---- convert bytes to a string (UTF-8) # --------------------------------------------------------------- title = byts[0:80].strip().decode('UTF-8') print(type(title))

Is System Big Endia or Little Endia?

# --------------------------------------------------------------- # ---- test if the system is 'big' endia or 'little' endia # --------------------------------------------------------------- import sys def test_for_little_endia(): if sys.byteorder=='big': return False return True

System Float Data Type

# --------------------------------------------------------------- # ---- system's float max, min, epsilon # --------------------------------------------------------------- import sys print("Max float value:", sys.float_info.max) print("Min float value:", sys.float_info.min) print("Machine epsilon:", sys.float_info.epsilon)

What Every Computer Scientist Should Know About
Floating-Point Arithmetic

Display Integer or Float as a String of Bits

#!/usr/bin/python3 # =============================================================== # display integer or float as a string of bits # '0' or '1' characters (all together or as separate bytes) # # For struct see: docs.python.org/3/library/struct.html # =============================================================== import struct # --------------------------------------------------------------- # ---- is a string an integer (function is not currently used) # --------------------------------------------------------------- def is_string_an_integer(s): return s.isdigit() # --------------------------------------------------------------- # ---- convert a number (float or integer) to a string of bits # --------------------------------------------------------------- def binary(s:str,separate=True) ->str: # ---- integer tf,num = ui.is_integer(s) if tf: print() print(f'convert "{s}" ({num}) to a string of bits') if separate: bits = ''.join(f'{byt:0>8b} ' \ for byt in struct.pack('i',num)) else: bits = ''.join(f'{byt:0>8b}' \ for byt in struct.pack('i',num)) return bits # ---- float (4 bytes) tf,num = ui.is_float(s) if tf: print() print(f'convert "{s}" ({num}) to a string of bits') if separate: bits = ''.join(f'{byt:0>8b} ' \ for byt in struct.pack('f',num)) else: bits = ''.join(f'{byt:0>8b}' \ for byt in struct.pack('f',num)) return bits # ---- not a number return None # --------------------------------------------------------------- # ---- main # --------------------------------------------------------------- if __name__ == '__main__': import sys import user_interface as ui print() print(f'System is {sys.byteorder} endia') print() while True: print() s = ui.get_user_input('Enter a number: ') if not s: break bits = binary(s) if bits is None: print() print(f'bad input ({s}) - try again') continue print() print(bits)