| Crates.io | wlgen-rs |
| lib.rs | wlgen-rs |
| version | 0.2.1 |
| created_at | 2026-01-16 21:43:58.860754+00 |
| updated_at | 2026-01-16 21:58:46.706416+00 |
| description | High-performance wordlist generator for hashcat - achieving 100-200M combinations/second |
| homepage | |
| repository | https://github.com/tehw0lf/wlgen-rs |
| max_upload_size | |
| id | 2049317 |
| size | 118,608 |
CPU-based Rust wordlist generator achieving ~164M combinations/second - 11% faster than maskprocessor!
⚡ For Maximum Performance: See GPU Scatter-Gather Wordlist Generator for 500M-1B words/s using GPU acceleration and novel algorithms.
wlgen-rs is a CPU-based Rust wordlist generator that uses an efficient "odometer" algorithm (similar to hashcat's maskprocessor) to generate wordlists. It's designed as a CPU fallback and reference implementation.
Current Performance (2025-11-07 Optimized):
This project serves as:
For high-performance wordlist generation (500M-1B words/s), use the GPU Scatter-Gather project instead.
Suitable for:
Consider GPU alternative for:
git clone https://github.com/tehw0lf/wlgen-rs
cd wlgen-rs
cargo build --release
The binary will be available at target/release/wlgen-rs.
cargo install wlgen-rs
# Generate simple 2-character wordlist
wlgen-rs -1 'abc' -2 '123' '?1?2'
# Output: a1, a2, a3, b1, b2, b3, c1, c2, c3
# Use built-in charsets (hashcat-compatible)
wlgen-rs '?l?d?d?d' # lowercase letter + 3 digits (e.g., a000, a001, ..., z999)
wlgen-rs '?u?l?l?d?d' # uppercase + 2 lowercase + 2 digits
# Pipe to hashcat for WPA2 cracking
wlgen-rs -1 'ABCDEF' -2 '0123456789' '?1?1?2?2?2?2?2?2' | hashcat -m 2500 capture.hccapx
# Save to file with automatic compression
wlgen-rs '?l?d?d?d' -o wordlist.txt.gz # gzip compression
wlgen-rs '?l?d?d?d' -o wordlist.txt.zst # zstd compression (requires --features compression)
# Resume from specific position (distributed workloads)
wlgen-rs --skip 1000000 '?l?d?d?d' -o part2.txt
# Show progress and ETA
wlgen-rs --progress '?l?d?d?d?d' -o wordlist.txt
# Complex pattern with multiple charsets
wlgen-rs -1 'ABCDEF' -2 '0123456789' -3 '!@#$' '?1?1?2?2?3'
# Mix built-in and custom charsets
wlgen-rs -1 'XYZ' '?l?1?d' # lowercase + custom charset + digit
# Mix literal characters with placeholders
wlgen-rs -1 'abc' 'prefix?1?1suffix'
wlgen-rs [OPTIONS] <MASK>
Arguments:
<MASK> Mask pattern (e.g., "?1?1?2?2", "?l?d?d?d")
Options:
-1, --custom-charset1 <CS> Custom charset 1
-2, --custom-charset2 <CS> Custom charset 2
-3, --custom-charset3 <CS> Custom charset 3
-4, --custom-charset4 <CS> Custom charset 4
-5, --custom-charset5 <CS> Custom charset 5
-6, --custom-charset6 <CS> Custom charset 6
-7, --custom-charset7 <CS> Custom charset 7
-8, --custom-charset8 <CS> Custom charset 8
-9, --custom-charset9 <CS> Custom charset 9
-o, --output <FILE> Output file (default: stdout). Supports .gz and .zst for compression
--skip <N> Skip first N combinations (for resuming or distributed workloads)
--progress Show progress and ETA (writes to stderr)
-h, --help Print help
-V, --version Print version
Building with Compression Support:
# Build with all compression formats (gzip + zstd)
cargo build --release --features compression
# Build with gzip only
cargo build --release --features gzip
# Build with zstd only
cargo build --release --features zstd-compression
Mask patterns support two types of placeholders:
?l - lowercase letters (a-z)?u - uppercase letters (A-Z)?d - digits (0-9)?s - special characters (space and punctuation)?a - all printable ASCII (?l + ?u + ?d + ?s)?b - all bytes (0x00-0xFF)Use ?N placeholders where N is 1-9, referencing custom charsets defined via command-line arguments.
?l?d?d - lowercase letter + 2 digits (a00, a01, ..., z99)?u?l?l?l - uppercase + 3 lowercase (Aaaa, Aaab, ..., Zzzz)?1?2 - Two positions using charset 1 and charset 2?1?1?1 - Three positions all using charset 1?l?1?d - Lowercase + custom charset 1 + digitprefix?1suffix - Literal characters mixed with charset placeholderBased on hashcat's maskprocessor implementation, wlgen-rs uses an "odometer" pattern:
This approach achieves:
use wlgen_rs::WordlistGenerator;
let charsets = vec![
b"abc".to_vec(),
b"123".to_vec(),
];
let mut gen = WordlistGenerator::new(charsets);
for word in gen {
println!("{}", word);
}
// Prints: a1, a2, a3, b1, b2, b3, c1, c2, c3
# Debug build
cargo build
# Release build (with optimizations)
cargo build --release
# Run all tests
cargo test
# Run only unit tests
cargo test --lib
# Run only integration tests
cargo test --test integration
# Run benchmarks
cargo bench
# Run specific benchmark
cargo bench -- small_wordlist
Expected performance on modern hardware:
The Cargo.toml includes aggressive optimizations for release builds:
[profile.release]
opt-level = 3 # Maximum optimizations
lto = true # Link-time optimization
codegen-units = 1 # Single codegen unit for better optimization
strip = true # Strip symbols for smaller binary
| Tool | Speed (words/s) | Relative Performance | Benchmark Date |
|---|---|---|---|
| GPU Scatter-Gather | 500M-1B | 3-6x faster than wlgen-rs | TBD |
| wlgen-rs (CPU, optimized) | ~164M | 11% faster than maskprocessor! | 2025-11-07 |
| maskprocessor (CPU) | ~147.5M | 0.90x (baseline C implementation) | 2025-11-07 |
| wlgen-rs (CPU, initial) | ~41.8M | 0.25x (before optimizations) | 2025-11-07 |
| Python wlgen | ~780K | 0.005x (211x slower) | 2025-10-15 |
Through systematic profiling and optimization, we achieved a 3.93x speedup over the initial implementation:
Optimization 1: Remove UTF-8 Validation (3.58x speedup)
writeln! macro called std::str::from_utf8() on every wordwrite_all()Optimization 2: Increase Buffer Size (1.16x additional speedup)
Final Performance:
Remaining Bottlenecks:
Further optimization would require unsafe code (SIMD, unchecked access) for ~5-10% gains, but at the cost of memory safety guarantees.
Core Features:
Performance Optimizations:
Advanced Features:
All planned features complete! 🎉
These would require unsafe code or sacrifice safety for minimal gains:
Current performance (164M words/s) already exceeds maskprocessor by 11%. Further optimization would sacrifice memory safety for diminishing returns.
The standalone binary approach is preferred for maximum portability and ease of use.
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
cargo testcargo benchtehw0lf tehwolf@protonmail.com