DeaD_EyE

pack/unpack data with zero padding

Jun 11th, 2021
885
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import math
  2. import struct
  3. from typing import List, Generator
  4.  
  5.  
  6. def padding(bits: int, amount: int):
  7.     """
  8.    Return size of data and the required padding fot fit the alignment of bytes
  9.    """
  10.     size = bits * amount
  11.     pad = 0
  12.     if size % 8:
  13.          pad = (2 ** math.ceil(math.log2(size))) - size
  14.     return size, pad
  15.  
  16.  
  17. def pack(values: int, bits: int) -> bytes:
  18.     """
  19.    Pack the values by required bits.
  20.    If a value is out of range, a ValueError is raised
  21.    """
  22.     size, pad = padding(bits, len(values))
  23.     result = 0
  24.  
  25.     for idx, value in enumerate(values):
  26.         if not 0 <= value < 2 ** bits:
  27.             raise ValueError("Value is not in allowed range")
  28.         result |= value << (idx * bits)
  29.  
  30.     return result.to_bytes(size + pad, "little")
  31.  
  32.  
  33.  
  34. def unpack(data: bytes, bits: int) -> Generator[List[int], None, None]:
  35.     """
  36.    Unpack bytes to integers with given bits.
  37.    """
  38.  
  39.     value = int.from_bytes(data, "little")
  40.  
  41.     while value:
  42.         yield value & 0xFF
  43.         value >>= bits
  44.  
  45.  
  46. data = pack([1,2,3,4,5], 12)
  47. print(list(unpack(data, 12)))
RAW Paste Data