Huffman coding in a single, dependency-free Python module - build the code, encode, decode, and see how much it saves.
- Builds an optimal prefix-free Huffman code from symbol frequencies (min-heap based)
- Works on
str(per character, full Unicode) andbytes(per byte, any binary file) - Packs the bit stream into bytes with a 4-byte header holding the exact bit count
- Decodes back to the original type and verifies the round trip
- Command-line demo that prints the code table and compression statistics
- Standard library only
python3 huffman.py # encode a built-in Lorem Ipsum sample
python3 huffman.py testdata.html # encode any file (read as bytes)The script prints each symbol's code (shortest first) followed by statistics:
Code Length (bits): 27728
Original Text Length (bits): 839728
Encoded Text Length (bits): 511880
Compression Percentage: 61.0%
Compression Percentage (with code): 64.3%
"with code" adds the size of the code table, which a decoder would need as well.
from huffman import decode_data, encode_data, get_huffman_code
text = "abracadabra"
code = get_huffman_code(text) # {'a': (0,), 'd': (1, 0, 0), ...}
encoded = encode_data(text, code) # bytes: 4-byte bit count + packed bits
assert decode_data(encoded, code) == textThe code table is not embedded in the encoded output; keep it alongside the data.
pip install pytest ruff
pytest # run the test suite
ruff check # lintCI runs both on every push and pull request against Python 3.9 to 3.14.
Every merge to main is tagged with the next patch version; bundled releases
with release notes come from the Release workflow.
| File | Purpose |
|---|---|
huffman.py |
Tree construction, encoder, decoder and CLI |
test_huffman.py |
Unit tests: round trips, code properties, edge cases |
testdata.html, testimage.jpg |
Sample inputs for text and binary encoding |
Changes start with an issue and go through a pull request; see CONTRIBUTING.
MIT - see LICENSE.