A Rust Base58 codec that decodes past 2 GiB/s, with scalar kernels. 100% safe Rust, #![forbid(unsafe_code)].
base58-turbo targets systems where CPU cycles are scarce. Every build is #![forbid(unsafe_code)] — there is no unsafe anywhere in the crate, on any target or feature combination. See Safety & Verification.
base58-turbo beats bs58, base58, base58-monero, and five8 at every payload size, peaking past 2 GiB/s on decode — over 2x five8's best and 20x+ bs58. See Benchmarks.
AWS c8a.large (AMD EPYC 9R45). See Benchmarks.
use base58_turbo::BITCOIN;
let encoded = BITCOIN.encode(b"Hello World").unwrap(); // Result<String, Error>
assert_eq!(encoded, "JxF12TrwUP45BMd");use base58_turbo::BITCOIN;
let decoded = BITCOIN.decode("JxF12TrwUP45BMd").unwrap(); // Result<Vec<u8>, Error>
assert_eq!(decoded, b"Hello World");For hot paths where heap allocation is too slow, write directly to a stack buffer:
use base58_turbo::BITCOIN;
let mut output = [0u8; 64];
let len = BITCOIN.encode_into(b"Hello World", &mut output).unwrap(); // Result<usize, Error>
assert_eq!(std::str::from_utf8(&output[..len]).unwrap(), "JxF12TrwUP45BMd");Native support for Monero's block-chunked Base58 format (8-byte blocks padded to 11 characters):
use base58_turbo::xmr;
let payload = b"Hello World"; // Typically 69-byte addresses
let encoded = xmr::encode(payload).unwrap(); // Result<String, Error>
let decoded = xmr::decode(&encoded).unwrap(); // Result<Vec<u8>, Error>Zero-allocation xmr::encode_into / xmr::decode_into are also provided.
BITCOIN: Standard Bitcoin alphabet.MONERO: Monero alphabet.RIPPLE: Ripple alphabet.FLICKR: Flickr alphabet.Engine::new(&[u8; 58]): Custom alphabets.
MSRV: Rust 1.87.0 or newer.
API stability: The public API (traits, structs, error types) is Stable and follows Semantic Versioning. It stays backward-compatible throughout the 0.3.x lifecycle.
Numbers below come straight from cargo bench (benches/encoding_bench.rs), comparing base58-turbo against bs58, base58, five8, and base58-monero at payload sizes 16–128 bytes. five8 only ships fixed-width 32/64-byte encoders.
AWS c8a.large (AMD EPYC 9R45), chart above: at 48 bytes, decode hits 2.36 GiB/s vs 97.9 MiB/s for bs58 (+2369%) and 79.2 MiB/s for base58 (+2954%). Against five8: decode wins at both sizes it supports (2.19 vs 1.11 GiB/s @ 32B, +97%; 2.34 vs 1.17 GiB/s @ 64B, +100%), and encode wins too (1.26 vs 0.87 GiB/s @ 32B, +44%; 1.32 vs 1.00 GiB/s @ 64B, +33%). XMR (block-chunked, slower than flat) still leads base58-monero by +142% decode / +390% encode at 48 bytes. Peak: 2.36 GiB/s decode, single-threaded.
AWS c7i.large (Intel Xeon Platinum 8488C), a smaller/cheaper box:
At 48 bytes: 1.59 GiB/s decode vs 84 MiB/s for bs58 (+1790%) and 60 MiB/s for base58 (+2553%). Against five8, decode wins clearly (1.38 vs 0.78 GiB/s @ 32B, +76%; 1.67 vs 0.70 GiB/s @ 64B, +139%), but encode is closer — five8 edges ahead at 32B (0.70 vs 0.74 GiB/s, -5%) before base58-turbo retakes the lead at 64B (0.62 vs 0.55 GiB/s, +13%). Both machines show the same relative ordering and shape, differing by ~1.5x in absolute ceiling — the 2 GiB/s+ figure is a real peak on real hardware, not a universal constant.
Reproduce on a fresh checkout with nothing else running:
sudo apt update && sudo apt install -y build-essential git
curl --proto '=https' --tlsv1.3 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
git clone https://github.com/hacer-bark/base58-turbo
cd base58-turbo
RUSTFLAGS="-C target-cpu=native" BENCH_TARGET=all cargo bench 2>&1 | tee benches/results/raw.txt
python3 benches/scripts/plot_bench.py benches/results/raw.txtRaw cargo bench output — AWS c8a.large
See benches/results/c8a-large-latest.txt for the
full output — 32 B through 10 MB, every target.
Raw cargo bench output — AWS c7i.large
See benches/results/c7i-large-latest.txt for the
full output — 32 B through 10 MB, every target.
#![forbid(unsafe_code)] applies unconditionally in lib.rs: no feature flag, target, or configuration reintroduces unsafe. The compiler rejects any unsafe block anywhere in the crate — no pointer arithmetic, no manually-asserted invariant to audit. Performance comes entirely from the base conversion algorithm and from shaping the hot loops so the compiler can drop bounds checks on its own.
The test suite guards against ordinary logic bugs: exact conformance vectors, every kernel-dispatch and scratch-buffer boundary, and randomized cross-validation against bs58, base58, five8, and base58-monero. See .github/workflows/tests.yml.
| Feature | Default | Description |
|---|---|---|
std |
Yes | String/Vec support; disable for no_std |
Licensed under the 0BSD license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate shall be licensed as above, without any additional terms or conditions.

