fingerprint-rs
A high-performance Rust library for generating statistically realistic browser fingerprints and HTTP headers — built on Bayesian networks trained on real-world browser data.
Drop-in Rust alternative to Python's browserforge with full feature parity: navigator, screen, UA Client Hints, WebGL, codecs, battery, fonts, plugins, multimedia devices, and WebRTC flag.
✨ Key Features
| Feature | Description |
|---|---|
| Statistically realistic | Sampled from Bayesian networks trained on millions of real browser profiles via the Apify dataset |
| Full fingerprint coverage | Navigator, screen, UA Client Hints (high-entropy), WebGL videoCard, audio/video codecs, battery, fonts, plugins, multimedia devices |
| HTTP headers | Ordered, realistic HTTP headers (User-Agent, Accept, sec-ch-ua, etc.) |
| Deterministic | Seed-based generation for reproducible sessions across restarts |
| Constrained | Filter by browser family (Chrome, Firefox, Safari, Edge), OS (Windows, macOS, Linux, Android, iOS), and locale |
| Blazing fast | ~127µs per fingerprint (warm), 7,800+ generations/sec — faster than browserforge |
| Zero unsafe | #![deny(unsafe_code)] enforced across all crates |
| Tiny binary | Bayesian networks embedded at compile time via include_bytes! — no runtime IO |
📦 Installation
Add to your Cargo.toml:
[]
= { = "https://github.com/AstraSurge/fingerprint-generator" }
🚀 Quick Start
use ;
📖 API Reference
FingerprintGenerator — Fluent Builder
new // unconstrained builder
.browser // constrain browser
.os // constrain OS
.locale // constrain locale
.seeded // deterministic mode
.strict // error on unsatisfiable constraints
.generate?; // → Result<BrowserProfile>
random?; // shorthand for new().generate()
Browser & OS Constraints
// Browsers // Operating Systems
Chrome Windows
Firefox MacOs
Safari Linux
Edge Android
Other Ios
Other
BrowserProfile — Output Structure
BrowserFingerprint — Full Fingerprint Data
All fields match browserforge output 1:1 with camelCase JSON serialization:
NavigatorFingerprint — Detailed Navigator
UserAgentData — High-Entropy Client Hints
Chrome and Edge profiles include full UA Client Hints data:
📋 Full JSON Output Example
🔧 Usage Patterns
Generate HTTP Headers Only
use ;
let profile = new
.browser
.generate?;
// Use with reqwest, hyper, or any HTTP client
for in &profile.headers
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
// Accept: text/html,application/xhtml+xml,...
// sec-ch-ua: "Google Chrome";v="125", "Chromium";v="125", ...
Access Extended Fingerprint Fields
let profile = new.seeded.generate?;
let fp = &profile.fingerprint;
// WebGL Video Card
if let Some = &fp.video_card
// Battery Status
if let Some = &fp.battery
// UA Client Hints (Chromium only)
if let Some = &fp.navigator.user_agent_data
// Detected Fonts
if let Some = &fp.fonts
// WebRTC Flag
println!; // Some(true) for Chrome/Edge
Session-Based Deterministic Generation
use DefaultHasher;
use ;
// Same session ID → identical fingerprint every time
let profile = new
.seeded
.browser
.os
.generate?;
Strict Mode & Error Handling
use FingerprintError;
match new
.browser
.os
.strict
.generate
| Error Variant | When |
|---|---|
ConstraintConflict |
Known impossible combo (e.g., Safari + Windows) |
ConstraintsTooRestrictive |
Sampler exhausted retry budget (only with .strict()) |
NetworkParseError |
Embedded Bayesian network is corrupt (should never happen) |
SamplingFailed |
Internal sampler error |
📚 Examples
Run any example with:
| Example | Description | browserforge equivalent |
|---|---|---|
basic |
Core API usage patterns | FingerprintGenerator().generate() |
full_output |
Complete JSON output for comparison | json.dumps(fg.generate().__dict__) |
headers |
HTTP header generation & integration | HeaderGenerator(browser='chrome').generate() |
extended |
All extended fields: GPU, codecs, battery, fonts, plugins | Full fingerprint inspection |
all_browsers |
Side-by-side browser comparison | Multi-browser generation |
seeded_batch |
Session-based deterministic generation | Reproducible sessions |
benchmark |
Performance measurement | Throughput comparison |
⚡ Performance
Benchmarked on Apple M-series (release build):
| Metric | Result |
|---|---|
| Cold start (first call) | ~70ms (includes network decompression) |
| Warm (unconstrained) | ~127µs/call → 7,800+ fps |
| Warm (constrained Chrome+Windows) | ~181µs/call → 5,500+ fps |
Comparison: browserforge (Python) reports 0.1–0.2ms per generation. fingerprint-rs matches or exceeds this performance while running in pure Rust with zero FFI overhead.
🏗️ Architecture
Workspace Structure
fingerprint-generator/ ← Cargo workspace root
├── fingerprint-core/ ← Shared types & errors
│ └── src/types/fingerprint.rs ← BrowserProfile, NavigatorFingerprint, etc.
├── fingerprint-data/ ← Embedded Bayesian network ZIPs
│ ├── data/ ← header-network.zip, fingerprint-network.zip
│ └── src/loader.rs ← Lazy decompression via OnceLock
└── fingerprint-rs/ ← Public API crate
├── src/
│ ├── generator.rs ← FingerprintGenerator builder
│ ├── assembler.rs ← Raw network → BrowserProfile mapping
│ └── engine/ ← Bayesian sampler (ancestral + constrained)
└── examples/ ← 7 runnable examples
Dual-Network Architecture
fingerprint-rs uses two independent Bayesian networks:
- Header Network — generates realistic HTTP headers, browser family, OS, and device type. Constraints (browser, OS) are applied here via rejection sampling.
- Fingerprint Network — generates JavaScript API values (navigator, screen, WebGL, codecs, etc.). Sampled independently from the header network.
The assembler then merges outputs from both networks into a coherent BrowserProfile, deriving computed fields like mockWebRTC from the header network's browser family.
Advanced: Lower-Level API
Access the Bayesian network and sampler directly for custom use cases:
use ;
use get_header_network;
use SeedableRng;
use ChaCha8Rng;
let network = get_header_network?;
let mut rng = seed_from_u64;
// Unconstrained sample — raw node assignments
let assignment = sample_ancestral?;
// Constrained sample — rejection sampling with target values
let mut constraints = new;
constraints.insert;
let assignment = sample_constrained?;
🔍 browserforge Feature Parity
| Feature | browserforge (Python) | fingerprint-rs (Rust) |
|---|---|---|
| Navigator (UA, platform, vendor) | ✅ | ✅ |
| HTTP Headers (ordered) | ✅ | ✅ |
| Screen (resolution, DPR) | ✅ | ✅ |
| Screen extended (outer*, avail*, client*) | ✅ | ✅ |
| UA Client Hints (high-entropy) | ✅ | ✅ |
| WebGL VideoCard (renderer, vendor) | ✅ | ✅ |
| Audio Codecs (ogg, mp3, wav, m4a, aac) | ✅ | ✅ |
| Video Codecs (ogg, h264, webm) | ✅ | ✅ |
| Battery Status (charging, level, time) | ✅ | ✅ |
| Fonts (detected font families) | ✅ | ✅ |
| Plugins & MIME types | ✅ | ✅ |
| Multimedia Devices (speakers, micros, webcams) | ✅ | ✅ |
| mockWebRTC flag | ✅ | ✅ |
| Browser constraint | ✅ | ✅ |
| OS constraint | ✅ | ✅ |
| Device constraint (mobile/desktop) | ✅ | 🔜 |
| Seeded/deterministic generation | ❌ | ✅ |
| Strict mode (fail on impossible combos) | ❌ | ✅ |
| Playwright/Puppeteer injector | ✅ | 🔜 |
🧪 Testing
# Run the full test suite (58 tests across 3 crates)
# Run with clippy (zero warnings enforced)
The test suite includes:
- Structural tests — profile shape, field presence, JSON serialization
- Constraint tests — browser/OS filtering, conflict detection, strict mode
- Extended field tests — videoCard, codecs, battery, fonts, plugins, UAD, mockWebRTC
- Determinism tests — seed reproducibility, different seeds → different outputs
- Header sanitization — no internal meta-keys (
*BROWSER,*DEVICE) leak to output
📜 Data Source
Browser fingerprint distributions are derived from empirical data collected by Apify:
@apify/fingerprint-generator— fingerprint Bayesian network@apify/header-generator— header Bayesian network
The Bayesian network ZIP files are embedded at compile time via include_bytes! and validated by build.rs. No runtime file IO is required.