multi-base
multibase implementation in Rust.
A multibase encoding/decoding library with error handling, type safety, and
no_std support.
Table of Contents
- Features
- Install
- Usage
- Supported Bases
- Performance
- Security
- Concurrency
- CLI Tool
- Testing
- Maintainers
- Contribute
- License
Features
โจ Stable
- 142 tests (unit, integration, property-based, security, concurrency)
- Zero clippy warnings
- Thread safety verification
#![deny(unsafe_code)]
๐ Performance
- Zero-copy buffer reuse APIs
#[inline]on hot encode/decode paths- Pre-allocated exact-capacity encoding
๐ Type Safety
- Validated
EncodedStringnewtype - "Parse, don't validate" pattern
- Compile-time guarantees
๐ก๏ธ Security
- No panics on untrusted input
#![deny(unsafe_code)]enforced- Fuzzing infrastructure
- Input validation at all boundaries
๐งต Thread Safe
- All types are Send + Sync
- No interior mutability
- Verified with concurrent stress tests
๐ Documented
- API documentation with examples
- Security and concurrency guides
- CHANGELOG.md with migration notes
๐ Flexible
- 24 supported base encodings
- Strict and permissive decoding modes
no_stdsupport withalloc- WebAssembly compatible
Install
Add this to your Cargo.toml:
[]
= "1.0"
For no_std environments:
[]
= { = "1.0", = false }
Note: the crate is published as
multi-baseon crates.io and imported asmulti_basein Rust. The current published version is1.0.1.
MSRV: Rust 1.85 (Edition 2024)
Usage
Basic Usage
use ;
// Encode data
let encoded = encode;
println!; // "maGVsbG8gd29ybGQ"
// Decode data
let = decode?;
assert_eq!;
assert_eq!;
Buffer Reuse for Performance
When encoding/decoding multiple values, reuse buffers to avoid allocations:
use ;
let mut encode_buffer = Stringnew;
let mut decode_buffer = Vecnew;
for data in dataset
Type Safety with EncodedString
Use EncodedString for validated multibase strings:
use ;
// Parse and validate at construction
let encoded = new?;
// Base is known at compile time
assert_eq!;
// Decode directly
let data = encoded.decode?;
assert_eq!;
// Or use FromStr
let encoded: EncodedString = "md29ybGQ".parse?;
Error Handling
The library provides comprehensive error types with context:
use ;
match decode
Supported Bases
The library supports 24 base encodings:
| Base | Code | Alphabet |
|---|---|---|
| Identity | \0 |
8-bit binary (no encoding) |
| Base2 | 0 |
01 |
| Base8 | 7 |
01234567 |
| Base10 | 9 |
0123456789 |
| Base16 (Lower) | f |
0123456789abcdef |
| Base16 (Upper) | F |
0123456789ABCDEF |
| Base32 (Lower) | b |
RFC 4648 (no padding) |
| Base32 (Upper) | B |
RFC 4648 (no padding) |
| Base32Pad (Lower) | c |
RFC 4648 (with padding) |
| Base32Pad (Upper) | C |
RFC 4648 (with padding) |
| Base32Hex (Lower) | v |
RFC 4648 hex (no padding) |
| Base32Hex (Upper) | V |
RFC 4648 hex (no padding) |
| Base32HexPad (Lower) | t |
RFC 4648 hex (with padding) |
| Base32HexPad (Upper) | T |
RFC 4648 hex (with padding) |
| Base32Z | h |
z-base-32 (Tahoe-LAFS) |
| Base36 (Lower) | k |
0123456789abcdefghijklmnopqrstuvwxyz |
| Base36 (Upper) | K |
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| Base58 Flickr | Z |
Flickr alphabet |
| Base58 Bitcoin | z |
Bitcoin alphabet |
| Base64 | m |
RFC 4648 (no padding) |
| Base64Pad | M |
RFC 4648 (with padding) |
| Base64Url | u |
RFC 4648 URL-safe (no padding) |
| Base64UrlPad | U |
RFC 4648 URL-safe (with padding) |
| Base256Emoji | ๐ |
Emoji alphabet |
Performance
Encoding Performance: Base32 and Base64 are orders of magnitude faster than other bases due to byte alignment.
Optimization Tips:
- Use
encode_into()anddecode_into()for buffer reuse in loops - Prefer Base32 or Base64 for performance-critical applications
- Use Base58 or Base16 when human readability is important
Benchmarks: Run cargo bench to see performance on your system.
Security
- โ No panics on arbitrary untrusted input
- โ
#![deny(unsafe_code)]enforced at compile time - โ Input validation at all boundaries
- โ 17 dedicated security tests
- โ Fuzzing infrastructure with 4 targets (3 functional + 1 placeholder)
Best Practices:
- For untrusted input, always use strict mode:
decode(input, true) - Implement application-level size limits (see SECURITY.md)
- For binary data preservation, avoid Identity encoding (use Base64 instead)
See SECURITY.md for detailed security information.
Concurrency
All public types are fully thread-safe:
- โ
All types implement
Send+Sync - โ No interior mutability
- โ No data races possible
- โ Verified with 20 thread safety tests
Concurrent Usage:
use Arc;
use thread;
let data = new;
let handles: =
.map
.collect;
for handle in handles
See CONCURRENCY.md for detailed concurrency information.
CLI Tool
The crate includes a command-line tool for encoding/decoding, located in the
cli/ directory.
Build the CLI:
Example usage:
# Encode data
|
# Decode data
|
# Specify input directly
Testing
The crate has 142 tests:
- 142 tests total (excluding ignored tests)
- 12 unit tests
- 63 integration tests
- 16 property-based tests (using proptest)
- 17 security tests
- 20 thread safety tests
- 14 documentation tests
Run all tests:
Run specific test suites:
Run benchmarks:
Run fuzzing (requires cargo-fuzz):
Documentation
Generate and view the documentation:
Additional documentation:
- SECURITY.md - Security review and best practices
- CONCURRENCY.md - Thread safety analysis
- CHANGELOG.md - Version history and migration notes
Maintainers
This Repo: @dhuseby.
Captain: @dignifiedquire.
Contributors: @koushiro, and others.
Contribute
Contributions welcome! Please check out the issues.
Check out our contributing document for more information on how we work, and about contributing in general.
Please be aware that all interactions related to multiformats are subject to the IPFS Code of Conduct.
Development Guidelines
- Run
cargo fmtbefore committing - Run
cargo clippy -- -D warningsto check for issues - Add tests for new features
- Update documentation for API changes
- Run full test suite:
cargo test --all
Small note: If editing the README, please conform to the standard-readme specification.
License
MIT ยฉ Friedel Ziegelmayer