Permutix
A high-performance string permutation generator written in pure Python, designed to be as fast as the CPython interpreter will physically allow.
Usage
python permutix.py [options]
| Flag | Description | Default |
|---|---|---|
--start N |
Minimum string length | 1 |
--max N |
Maximum string length | unlimited |
--alpha |
Letters only | |
--alphanum |
Letters + digits | |
--alphanumsym |
Letters + digits + symbols | default |
--charset STR |
Custom character set | |
--resume STR |
Resume from a specific string |
Examples
python permutix.py --start 6 --max 10
python permutix.py --max 4 | your_tool
python permutix.py --start 6 --max 10 --resume aB3x.k
python permutix.py --alphanum --max 8
python permutix.py --charset "0123456789abcdef" --max 8
The Algorithm
Given a character set, the generator produces every possible string from a minimum length up to a maximum: a, b, ..., 9, aa, ab, ..., 99, aaa, and so on. Every combination, in order, exhaustively.
The core algorithm treats the current string as a mechanical odometer. Instead of recomputing each string from a number, we store it as an array of positions into the character set and increment it in place. Tick the last position up by one. If it rolls past the end of the charset, reset it to zero and carry into the next position to the left — exactly like a car's odometer rolling 999 to 1000.
[a, a, a] → [a, a, b] → ... → [a, a, 9] → [a, b, a] → ...
For a 95-character set, 94 out of every 95 iterations only touch the last digit — one comparison, one increment, done. The carry chain fires once every 95 ticks, and a full overflow that grows the string is astronomically rare. No division, no exponentiation, no memory allocation in the hot path.
Output is buffered into 200,000-string batches and written as raw bytes directly to sys.stdout.buffer, bypassing Python's text encoding layer entirely. The odometer maintains a parallel bytearray of the actual output characters, so producing each string is a single memcpy rather than a per-character build loop.
To go beyond CPython's interpreter ceiling, run under PyPy for a free 5-10x from JIT compilation, or rewrite the odometer as a C extension.