Advertisement
Zoinkity

Random, Very Small Huffman-Like Decompressor

Jan 12th, 2018
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.75 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. def _bits(d):
  4.     """Iterates bytes-like object d, returning requested #bytes.
  5.    Remember to initialize the iterator before use!
  6.    Using next(_bits()) returns the next bit in the sequence.
  7.    Use _bits.send() to request a given number of bits."""
  8.     # Magic!  Only if None will be 1!
  9.     n = (yield 0) or 1
  10.     o, c = 0, 0
  11.     for i in d:
  12.         while c >= n:
  13.             m = o & ((1 << n) - 1)
  14.             o >>= n
  15.             c -= n
  16.             n = (yield m) or 1
  17.         i <<= c
  18.         o |= i
  19.         c += 8
  20.  
  21. def _tbl(data):
  22.     """Creates two blank tables, then calls _huffy() to fill it.
  23.    Iterations return next value from the tree."""
  24.     # I'll admit, this looks a little too much like magic.
  25.     itr = _bits(data)
  26.     next(itr)
  27.     # The lower 0x100 entries of each table aren't used, but simplifies things.
  28.     tbl = list(bytes(0x400))
  29.     tbl.append(0x100)
  30.     # Table is sent via pointer, so you see the changes here too.
  31.     c = _huffy(itr, tbl)
  32.     #yield c
  33.     while True:
  34.         v = c
  35.         while v > 0xFF:
  36.             v = tbl[v + (itr.send(1) << 9)]
  37.         yield v
  38.  
  39. def _huffy(itr, tbl):
  40.     """Reentrant; fills table with entries from data stream.
  41.    Returns current index."""
  42.     if itr.send(1):
  43.         c = tbl[-1]
  44.         tbl[-1] += 1
  45.         tbl[c] = _huffy(itr, tbl)
  46.         tbl[c + 0x200] = _huffy(itr, tbl)
  47.         return c
  48.     return itr.send(8)
  49.  
  50. def decode(data):
  51.     # Read header.
  52.     c = data[0] & 3
  53.     dec_sz = int.from_bytes(data[1:4], 'big')
  54.     if c == 0:      # Copy
  55.         return data[4:]
  56.     elif c == 1:    # Huffman
  57.         c = _tbl(data[4:])
  58.         out = bytearray()
  59.         while len(out) < dec_sz:
  60.             out.append(next(c))
  61.         return out
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement