Skip to content

dozyio/base58

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

base58

High-performance Base58 encoding/decoding library for Go with support for multiple alphabets.

Features

  • Fast: Optimized algorithms using chunked processing and lookup tables
  • Multiple Alphabets: Built-in support for Bitcoin, Flickr, and Ripple alphabets
  • Memory Efficient: Minimal allocations (1-2 allocs for most operations), stack allocation for small inputs
  • Zero Dependencies: Pure Go implementation
  • Fully Tested: Comprehensive test suite with fuzzing

Installation

go get github.com/dozyio/base58

Usage

Basic Encoding/Decoding

package main

import (
    "fmt"
    "github.com/dozyio/base58"
)

func main() {
    // Encode using Bitcoin alphabet (default)
    data := []byte("Hello, World!")
    encoded := base58.Encode(data)
    fmt.Println(encoded) // 72k1xXWG59fYdzSNoA

    // Decode
    decoded, err := base58.Decode(encoded)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(decoded)) // Hello, World!
}

Custom Alphabets

// Use Flickr alphabet
encoded := base58.EncodeAlphabet(data, base58.FlickrAlphabet)
decoded, err := base58.DecodeAlphabet(encoded, base58.FlickrAlphabet)

// Use Ripple alphabet
encoded = base58.EncodeAlphabet(data, base58.RippleAlphabet)
decoded, err = base58.DecodeAlphabet(encoded, base58.RippleAlphabet)

// Create custom encoding instance
custom := base58.NewEncoding("your58characteralphabetgoesheremakesureitisunique123")
encoded = custom.Encode(data)
decoded, err = custom.Decode(encoded)

Performance

Benchmarked on Apple M3 Max against popular Go Base58 libraries:

Decode Performance

Input Size This Library mr-tron/base58 btcd Speedup vs mr-tron Speedup vs btcd Allocs vs mr-tron Allocs vs btcd
10 bytes 32.94 ns/op
1 alloc/op
60.02 ns/op
1 alloc/op
94.33 ns/op
5 allocs/op
1.82x faster 2.86x faster Equal 5x fewer
100 bytes 180.1 ns/op
1 alloc/op
3,396 ns/op
2 allocs/op
440.8 ns/op
7 allocs/op
18.9x faster 2.45x faster 2x fewer 7x fewer
1 KB 10,037 ns/op
106 allocs/op
470,766 ns/op
2 allocs/op
7,426 ns/op
30 allocs/op
46.9x faster 1.35x slower 53x more 3.5x more
10 KB 272,245 ns/op
751 allocs/op
48,694,924 ns/op
2 allocs/op
409,456 ns/op
260 allocs/op
179x faster 1.50x faster 376x more 2.9x more

Memory Allocations (Decode):

Input Size This Library mr-tron/base58 btcd
10 bytes 16 B/op
1 alloc/op
24 B/op
1 alloc/op
96 B/op
5 allocs/op
100 bytes 112 B/op
1 alloc/op
352 B/op
2 allocs/op
512 B/op
7 allocs/op
1 KB 13,660 B/op
106 allocs/op
3,456 B/op
2 allocs/op
17,024 B/op
30 allocs/op
10 KB 195,307 B/op
751 allocs/op
34,816 B/op
2 allocs/op
1,417,480 B/op
260 allocs/op

Encode Performance

Input Size This Library mr-tron/base58 btcd Speedup vs mr-tron Speedup vs btcd Allocs vs mr-tron Allocs vs btcd
10 bytes 39.05 ns/op
1 alloc/op
98.09 ns/op
1 alloc/op
79.44 ns/op
3 allocs/op
2.51x faster 2.03x faster Equal 3x fewer
100 bytes 581.1 ns/op
1 alloc/op
11,196 ns/op
2 allocs/op
754.4 ns/op
4 allocs/op
19.3x faster 1.30x faster 2x fewer 4x fewer
1 KB 46,754 ns/op
4 allocs/op
1,245,349 ns/op
2 allocs/op
46,893 ns/op
4 allocs/op
26.6x faster Equal 2x more Equal
10 KB 4,402,854 ns/op
4 allocs/op
125,558,953 ns/op
2 allocs/op
4,393,754 ns/op
4 allocs/op
28.5x faster Equal 2x more Equal

Memory Allocations (Encode):

Input Size This Library mr-tron/base58 btcd
10 bytes 16 B/op
1 alloc/op
16 B/op
1 alloc/op
72 B/op
3 allocs/op
100 bytes 144 B/op
1 alloc/op
288 B/op
2 allocs/op
440 B/op
4 allocs/op
1 KB 3,976 B/op
4 allocs/op
2,816 B/op
2 allocs/op
3,976 B/op
4 allocs/op
10 KB 39,560 B/op
4 allocs/op
28,672 B/op
2 allocs/op
39,560 B/op
4 allocs/op

libp2p Peer ID Performance

Optimized for typical libp2p peer ID sizes (34-byte SHA-256 multihash):

Operation This Library mr-tron/base58 btcd Speedup vs mr-tron Speedup vs btcd Allocs vs mr-tron Allocs vs btcd
Encode 102.6 ns/op
48 B/op
1 alloc/op
1,322 ns/op
96 B/op
2 allocs/op
210.7 ns/op
184 B/op
4 allocs/op
12.9x faster 2.05x faster 2x fewer 4x fewer
Decode 68.80 ns/op
48 B/op
1 alloc/op
346.9 ns/op
128 B/op
2 allocs/op
179.5 ns/op
160 B/op
5 allocs/op
5.04x faster 2.61x faster 2x fewer 5x fewer
Round-Trip 173.6 ns/op
96 B/op
2 allocs/op
1,714 ns/op
224 B/op
4 allocs/op
397.5 ns/op
344 B/op
9 allocs/op
9.87x faster 2.29x faster 2x fewer 4.5x fewer

Optimization Techniques

This library achieves high performance through several optimizations:

  1. Hybrid Approach: Automatically switches between optimized algorithms based on input size:
    • Small inputs (< 512 bytes for encode, < 768 bytes for decode): Uses chunked uint64 math with minimal allocations
    • Large inputs (≥ 512/768 bytes): Uses math/big which leverages assembly-optimized big integer operations
    • This hybrid strategy provides the best performance across all input sizes
  2. Chunked Processing: Processes input in Base58^5 (encode) and Base58^10 (decode) chunks instead of single bytes
  3. Lookup Tables: Pre-computed 2-character lookup table (58^2 = 3,364 entries) for faster output generation
  4. Stack Allocation: Uses stack allocation for small inputs to avoid heap pressure
  5. Unsafe Pointers: Direct memory access for critical hot paths
  6. SIMD-Ready: Byte reversal using bits.ReverseBytes32 for potential hardware acceleration
  7. Zero-Copy Strings: Uses unsafe.String to avoid allocations when converting []byte to string
  8. Alphabet Caching: Caches encoding instances to avoid rebuilding decode maps

API Reference

Functions

// Encode/Decode with Bitcoin alphabet
func Encode(input []byte) string
func Decode(str string) ([]byte, error)

// Encode/Decode with custom alphabet
func EncodeAlphabet(input []byte, alphabet string) string
func DecodeAlphabet(str string, alphabet string) ([]byte, error)

// Create encoding instance
func NewEncoding(alphabet string) *Encoding

Pre-defined Alphabets

const (
    BTCAlphabet    = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
    FlickrAlphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
    RippleAlphabet = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
)

Pre-initialized Encodings

var (
    BTC    = NewEncoding(BTCAlphabet)
    Flickr = NewEncoding(FlickrAlphabet)
    Ripple = NewEncoding(RippleAlphabet)
)

Testing

# Run tests
go test -v

# Run benchmarks
go test -bench=. -benchmem

# Run with race detection
go test -race

# Run fuzzing
go test -fuzz=FuzzBase58 -fuzztime=30s

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors