mirror of
https://github.com/jimeh/go-base58.git
synced 2026-02-18 23:56:40 +00:00
Switch from string to []byte slices
The way I'm using the base58 required me to do a lot conversions between
[]byte slices and strings. Not anymore.
Also switching to []byte slices allowed some nice performance
improvements.
Before, with strings:
BenchmarkEncode-4 3000000 511 ns/op
BenchmarkDecode-4 5000000 300 ns/op
After, with []byte slices:
BenchmarkEncode-4 5000000 256 ns/op
BenchmarkDecode-4 20000000 107 ns/op
This commit is contained in:
30
base58.go
30
base58.go
@@ -1,38 +1,41 @@
|
|||||||
package base58
|
package base58
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Alphabet is the default alphabet.
|
// Alphabet is the default alphabet.
|
||||||
const Alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
|
var Alphabet = []byte(
|
||||||
const base = len(Alphabet)
|
"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ",
|
||||||
|
)
|
||||||
|
var base = len(Alphabet)
|
||||||
|
|
||||||
var errInvalidBase58 = errors.New("invalid base58")
|
var errInvalidBase58 = errors.New("invalid base58")
|
||||||
|
|
||||||
// Encode converts a base10 integer to a base58 string using the default
|
// Encode converts a base10 integer to a base58 string using the default
|
||||||
// alphabet.
|
// alphabet.
|
||||||
func Encode(num int) string {
|
func Encode(num int) []byte {
|
||||||
str := ""
|
str := []byte{}
|
||||||
|
|
||||||
for num >= base {
|
for num >= base {
|
||||||
mod := num % base
|
mod := num % base
|
||||||
str = string(Alphabet[mod]) + str
|
str = prepend(str, Alphabet[mod])
|
||||||
num = (num - mod) / base
|
num = (num - mod) / base
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(Alphabet[num]) + str
|
return prepend(str, Alphabet[num])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode converts a base58 string to a base10 integer using the default
|
// Decode converts a base58 string to a base10 integer using the default
|
||||||
// alphabet.
|
// alphabet.
|
||||||
func Decode(str string) (int, error) {
|
func Decode(str []byte) (int, error) {
|
||||||
num := 0
|
num := 0
|
||||||
multi := 1
|
multi := 1
|
||||||
|
|
||||||
for i := len(str); i > 0; i-- {
|
for i := len(str); i > 0; i-- {
|
||||||
char := string(str[i-1])
|
char := str[i-1]
|
||||||
index := strings.Index(Alphabet, char)
|
index := bytes.IndexByte(Alphabet, char)
|
||||||
if index == -1 {
|
if index == -1 {
|
||||||
return -1, errInvalidBase58
|
return -1, errInvalidBase58
|
||||||
}
|
}
|
||||||
@@ -42,3 +45,10 @@ func Decode(str string) (int, error) {
|
|||||||
|
|
||||||
return num, nil
|
return num, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prepend(slice []byte, elem byte) []byte {
|
||||||
|
slice = append(slice, byte(0))
|
||||||
|
copy(slice[1:], slice)
|
||||||
|
slice[0] = elem
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|||||||
@@ -186,26 +186,28 @@ type Base58Suite struct {
|
|||||||
// Tests
|
// Tests
|
||||||
|
|
||||||
func (s *Base58Suite) TestAlphabet() {
|
func (s *Base58Suite) TestAlphabet() {
|
||||||
expected := "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
|
s.Equal(
|
||||||
s.Equal(expected, Alphabet)
|
[]byte("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"),
|
||||||
|
Alphabet,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Base58Suite) TestEncode() {
|
func (s *Base58Suite) TestEncode() {
|
||||||
for str, num := range examples {
|
for str, num := range examples {
|
||||||
result := Encode(num)
|
result := Encode(num)
|
||||||
s.Equal(str, result)
|
s.Equal([]byte(str), result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Base58Suite) TestDecode() {
|
func (s *Base58Suite) TestDecode() {
|
||||||
for str, num := range examples {
|
for str, num := range examples {
|
||||||
result, _ := Decode(str)
|
result, _ := Decode([]byte(str))
|
||||||
s.Equal(num, result)
|
s.Equal(num, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Base58Suite) TestDecodeError() {
|
func (s *Base58Suite) TestDecodeError() {
|
||||||
result, err := Decode("invalid@base58.string")
|
result, err := Decode([]byte("invalid@base58.string"))
|
||||||
|
|
||||||
s.Equal(-1, result)
|
s.Equal(-1, result)
|
||||||
s.Equal("invalid base58", err.Error())
|
s.Equal("invalid base58", err.Error())
|
||||||
@@ -227,6 +229,6 @@ func BenchmarkEncode(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkDecode(b *testing.B) {
|
func BenchmarkDecode(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
_, _ = Decode("6hKMCS")
|
_, _ = Decode([]byte("6hKMCS"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user