#!/bin/bash
[rahul@fedora ~/projects]$ cat bit-compress.md

bit-compress

C · Python · bit-level RLE + byte-level Huffman · lossless round-trip verification

bit-compress is a lossless data compression engine that pairs two classical algorithms with an automatic selection layer. The C side implements both codecs: a bit-level run-length encoder, effective on clustered low-entropy bit streams, and a byte-level Huffman coder built from a frequency table and a min-heap tree with a node pool, emitting prefix codes into a bit-packed payload with a frequency and size header so the identical tree can be reconstructed at decode time. Python sits in front as the orchestrator, deciding which codec to use, reporting statistics and verifying the result.

The selection is empirical rather than heuristic. Given a file or a raw byte string, the front-end runs both codecs and keeps whichever actually produced the smaller output, then wraps it in a small self-describing BCMP header carrying a magic value, the algorithm choice and the original size so the correct decompressor can be dispatched later. The CLI reports initial size, final size, compression ratio and elapsed time, and the pipeline round-trips every result to confirm the decompressed output matches the input byte for byte.

A significant part of the work went into constant factors rather than asymptotics. The test-data generator was rewritten from a per-bit Python loop into direct byte construction that samples only the sparse set bits, moving it from O(N) to roughly O(N/8 + number of ones). The RLE decompressor's inner per-bit expansion loop was replaced with a partial-byte fill followed by bulk emission of full 0x00 or 0xFF bytes, so the work for a run of length L drops from O(L) shifts to O(1 + L/8). The system stays O(N) overall with markedly better practical performance on the data it targets.

The project also documents its own failure mode honestly: early versions run against uniformly random data produced negative compression, because RLE's run-count overhead exceeds any saving when there are no runs to exploit. Adding the Huffman path and a biased generator turned that dead end into the design principle behind the current version — give the user the better of two simple algorithms for whatever binary data is actually presented, and prove losslessness rather than assume it.