Base58 is a pure Go implementation of the Bitcoin Base58 encoding and decoding scheme, based on and following a similar API as the official Go stdlib encoding/base64 package.
Unlike other implementations (such as the btcutil version that uses big.Int for arithmetic), this Base58 package uses custom repeated division routines that work on raw byte slices. This approach offers:
- Speed & Memory Efficiency: Fewer allocations and less overhead for typical input sizes (e.g. crypto addresses, public key hashes, short strings).
- Familiar API: Modeled on Go’s standard
encoding/base64
package for ease of use and consistency. - Stream Support: Provides stream encoder and decoder wrappers via
NewEncoder
andNewDecoder
.
-
NewEncoding(alphabet string) Encoding
Returns a new Base58 encoding scheme using the specified 58-character alphabet. -
StdEncoding
A pre-initializedEncoding
using the standard Bitcoin alphabet:
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
-
(enc Encoding) Encode(dst, src []byte) int
Encodessrc
into Base58, writes the result todst
, and returns the number of bytes written. -
(enc Encoding) EncodeToBytes(src []byte) []byte
Returns the Base58 encoding ofsrc
as a byte slice. -
(enc Encoding) EncodeToString(src []byte) string
Returns the Base58 encoding ofsrc
as a string.
-
(enc Encoding) Decode(dst, src []byte) (int, error)
Decodes Base58-encodedsrc
intodst
and returns the number of decoded bytes along with an error if any. -
(enc Encoding) DecodeToBytes(src []byte) ([]byte, error)
Returns a byte slice containing the decoded data from Base58-encodedsrc
. -
(enc Encoding) DecodeString(s string) ([]byte, error)
Decodes the Base58 strings
and returns the corresponding byte slice.
-
NewEncoder(enc Encoding, w io.Writer) io.WriteCloser
Returns a new stream encoder that writes Base58-encoded data tow
. The data is buffered and encoded whenClose()
is called. -
NewDecoder(enc Encoding, r io.Reader) io.Reader
Returns a new stream decoder that reads Base58-encoded data fromr
and provides the decoded output.
package main
import (
"fmt"
"log"
"github.com/cyclone-github/base58"
)
func main() {
data := []byte("hello world")
encoded := base58.StdEncoding.EncodeToString(data)
fmt.Println("Encoded:", encoded)
decoded, err := base58.StdEncoding.DecodeString(encoded)
if err != nil {
log.Fatalf("Decode error: %v", err)
}
fmt.Println("Decoded:", string(decoded))
}
package main
import (
"bytes"
"fmt"
"io"
"log"
"github.com/cyclone-github/base58"
)
func main() {
// Example of streaming encoding:
var encodedBuffer bytes.Buffer
encoder := base58.NewEncoder(base58.StdEncoding, &encodedBuffer)
encoder.Write([]byte("streaming data"))
encoder.Close()
fmt.Println("Stream Encoded:", encodedBuffer.String())
// Example of streaming decoding:
decoder := base58.NewDecoder(base58.StdEncoding, &encodedBuffer)
decodedBytes, err := io.ReadAll(decoder)
if err != nil {
log.Fatalf("Stream decode error: %v", err)
}
fmt.Println("Stream Decoded:", string(decodedBytes))
}
This Base58 package closely follows the design of Go’s encoding/base64
package:
-
API Parity:
Both packages use anEncoding
type with methods likeEncodeToString
andDecodeString
, making the Base58 API familiar to Go developers. -
Stream Processing:
Just like the base64 package, this package provides stream encoder and decoder wrappers throughNewEncoder
andNewDecoder
. -
Efficiency:
While the standard library’s base64 handles 6-bit groups for Base64 conversion, this Base58 package uses custom repeated division routines on raw byte slices. Compared to other Base58 implementations that rely onmath/big
, this approach avoids the overhead of arbitrary-precision arithmetic, thus offering improved performance for typical inputs. -
Extensibility:
The package can easily be extended to support alternate Base58 alphabets or custom variants, similar to how custom encodings can be created withencoding/base64
.
To install, run:
go get github.com/cyclone-github/base58
Then import the package in your project:
import "github.com/cyclone-github/base58"
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.