70 lines
1.4 KiB
Go
70 lines
1.4 KiB
Go
package base58
|
|
|
|
// 20% of AI generated code
|
|
// human made; AI enhanced
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"math/big"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidBase58Character = errors.New("invalid character in base58 string")
|
|
)
|
|
|
|
const alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
|
|
var revAlphabet = func() map[byte]int {
|
|
m := make(map[byte]int)
|
|
for i := range len(alphabet) {
|
|
m[alphabet[i]] = i
|
|
}
|
|
return m
|
|
}()
|
|
|
|
var b58 = big.NewInt(58)
|
|
var b256 = big.NewInt(256)
|
|
var estimate = math.Log(256) / math.Log(58)
|
|
|
|
func Encode(input []byte) string {
|
|
number := new(big.Int).SetBytes(input)
|
|
if number.Sign() == 0 {
|
|
return string(alphabet[0])
|
|
}
|
|
|
|
bufCap := int(float64(len(input))*estimate) + 8
|
|
buf := make([]byte, 0, bufCap)
|
|
|
|
mod := new(big.Int)
|
|
for number.Sign() > 0 {
|
|
number.DivMod(number, b58, mod)
|
|
if cap(buf) > len(buf) {
|
|
buf = buf[:len(buf)+1]
|
|
copy(buf[1:], buf[:len(buf)-1+1])
|
|
buf[0] = alphabet[mod.Int64()]
|
|
} else {
|
|
tmp := make([]byte, 1, cap(buf)+1)
|
|
tmp[0] = alphabet[mod.Int64()]
|
|
buf = append(tmp, buf...)
|
|
}
|
|
}
|
|
|
|
return string(buf)
|
|
}
|
|
|
|
func Decode(input string) ([]byte, error) {
|
|
number := big.NewInt(0)
|
|
for i := 0; i < len(input); i++ {
|
|
c := input[i]
|
|
val, ok := revAlphabet[c]
|
|
if !ok {
|
|
return nil, ErrInvalidBase58Character
|
|
}
|
|
number.Mul(number, b58)
|
|
number.Add(number, big.NewInt(int64(val)))
|
|
}
|
|
|
|
return number.Bytes(), nil
|
|
}
|