Zeckendorf Compression
A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm.
Overview
The Zeckendorf algorithm represents numbers as a sum of non-consecutive Fibonacci numbers. This library interprets input data as a big integer (either big-endian or little-endian), converts it to its Zeckendorf representation, and sometimes achieves compression. However, compression is not guaranteed; the algorithm may result in a larger representation depending on the input data. The library can automatically try both endian interpretations and select the one that produces the best compression.
Features
- Compression & Decompression: Convert data to/from Zeckendorf representation
- Multiple Endian Interpretations: Support for both big-endian and little-endian input interpretations
- Automatic Best Compression: Try both endian interpretations and automatically select the best result
- Multiple Fibonacci Algorithms:
- Slow recursive (memoized, for small numbers)
- Slow iterative (memoized, for large numbers)
- Fast Doubling (optimized, ~160x faster for large indices)
- BigInt Support: Handle arbitrarily large numbers using
num-bigint - Memoization: Thread-safe caching for improved performance
- Statistics & Visualization: Generate compression statistics and plots
- Benchmarking: Comprehensive performance benchmarks
- WebAssembly Support: Available as a WebAssembly module for use in web browsers
WebAssembly
This library is also available as a WebAssembly module for use in web browsers. Available functions are marked with the #[wasm_bindgen] attribute. The WebAssembly module can be built using the convenience script at scripts/build_wasm_bundle.sh that builds the WebAssembly module with the wasm-pack tool.
You can see a live demo of the WebAssembly module in action at https://prizz.github.io/zeckendorf-webapp/. The source code for the demo is available at https://github.com/pRizz/zeckendorf-webapp.
Installation
Install from crates.io
Run:
Or add this to your Cargo.toml:
[]
= "0.1.0"
For plotting features:
[]
= { = "0.1.0", = ["plotting"] }
Install from GitHub (development version)
Run:
Or add this to your Cargo.toml:
[]
= { = "https://github.com/pRizz/zeckendorf" }
For plotting features:
[]
= { = "https://github.com/pRizz/zeckendorf", = ["plotting"] }
Install from npm
Run:
Or add this to your package.json:
Usage
Basic Compression/Decompression
Big-Endian Interpretation
use ;
// Compress data (interpreted as big-endian integer)
let data = vec!;
let compressed = zeckendorf_compress_be;
// Decompress data
let decompressed = zeckendorf_decompress_be;
assert_eq!;
Little-Endian Interpretation
use ;
// Compress data (interpreted as little-endian integer)
let data = vec!;
let compressed = zeckendorf_compress_le;
// Decompress data
let decompressed = zeckendorf_decompress_le;
assert_eq!;
Automatic Best Compression
use ;
// Try both endian interpretations and get the best result
let data = vec!;
let result = zeckendorf_compress_best;
match result
Fibonacci Numbers
use memoized_slow_fibonacci_recursive;
// Calculate Fibonacci numbers (for indices up to 93)
let fib_10 = memoized_slow_fibonacci_recursive; // Returns 55
// For larger numbers, use BigInt versions
use fast_doubling_fibonacci_bigint;
let fib_100 = fast_doubling_fibonacci_bigint;
Zeckendorf Representation
use memoized_zeckendorf_list_descending_for_integer;
// Get Zeckendorf representation as a list of Fibonacci indices
let zld = memoized_zeckendorf_list_descending_for_integer;
// Returns [6, 4, 2] meaning F(6) + F(4) + F(2) = 8 + 3 + 1 = 12
Binaries
The project includes several utility binaries:
Main Playground
A playground/scratchpad for testing library functions.
Generate Test Data
Generates random test data files in the generated_data/ directory.
Example:
Generate Statistics
Generates comprehensive compression statistics and plots:
- Compression ratios across different input sizes
- Chance of compression being favorable
- Average and median compression ratios
- Statistics saved to
statistics_history/directory - Plots saved to
plots/directory
Plot Compression Ratios
Generates visualization plots of:
- Fibonacci numbers
- Compression ratios for various input ranges
Benchmarks
Zeckendorf Compression Benchmarks
Benchmarks compression, decompression, and round-trip performance for various data sizes (4 bytes to 16KB).
Fibonacci Benchmarks
Compares performance of different Fibonacci calculation algorithms:
- Slow iterative method
- Fast doubling method (~160x faster for large indices)
Working with Benchmark Baselines
Save a new baseline:
Compare to an existing baseline:
Performance Characteristics
- Fast Doubling Fibonacci: ~160x faster than iterative method for the 100,000th Fibonacci number
- Memoization: Thread-safe caching significantly improves repeated calculations. The trade-off is that the cache takes up memory.
- Compression Effectiveness: Varies by input; compression ratios oscillate and become less favorable as input size increases
Algorithm Details
Zeckendorf Representation
Every positive integer can be uniquely represented as a sum of non-consecutive Fibonacci numbers. For example:
- 12 = 8 + 3 + 1 = F(6) + F(4) + F(2)
Compression Process
- Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use
zeckendorf_compress_bestto try both) - The integer is converted to its Zeckendorf representation (list of Fibonacci indices)
- The representation is encoded as bits (use/skip bits)
- Bits are packed into bytes (little-endian output)
The library provides functions to compress with either interpretation, or you can use zeckendorf_compress_best to automatically try both and select the one that produces the smallest output.
Effective Fibonacci Indices
The library uses "Effective Fibonacci Indices" (EFI) starting from 0, where:
- EFI 0 = Fibonacci Index 2 (value 1)
- EFI 1 = Fibonacci Index 3 (value 2)
- etc.
This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
Limitations
- Compression is not guaranteed—some inputs may result in larger output
- Compression effectiveness decreases as input size increases
- The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
- Compression of large amounts of data causes memory issues. It is currently not recommended to compress files larger than 100,000 bytes.
License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
References
- Fast Fibonacci Algorithms - Fast doubling algorithm reference
- Zeckendorf's Theorem - Every positive integer has a unique representation as a sum of non-consecutive Fibonacci numbers