76 lines
1.4 KiB
Go
76 lines
1.4 KiB
Go
|
// Copyright (c) 2013-2015 The btcsuite developers
|
||
|
// Use of this source code is governed by an ISC
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package base58
|
||
|
|
||
|
import (
|
||
|
"math/big"
|
||
|
)
|
||
|
|
||
|
//go:generate go run genalphabet.go
|
||
|
|
||
|
var bigRadix = big.NewInt(58)
|
||
|
var bigZero = big.NewInt(0)
|
||
|
|
||
|
// Decode decodes a modified base58 string to a byte slice.
|
||
|
func Decode(b string) []byte {
|
||
|
answer := big.NewInt(0)
|
||
|
j := big.NewInt(1)
|
||
|
|
||
|
scratch := new(big.Int)
|
||
|
for i := len(b) - 1; i >= 0; i-- {
|
||
|
tmp := b58[b[i]]
|
||
|
if tmp == 255 {
|
||
|
return []byte("")
|
||
|
}
|
||
|
scratch.SetInt64(int64(tmp))
|
||
|
scratch.Mul(j, scratch)
|
||
|
answer.Add(answer, scratch)
|
||
|
j.Mul(j, bigRadix)
|
||
|
}
|
||
|
|
||
|
tmpval := answer.Bytes()
|
||
|
|
||
|
var numZeros int
|
||
|
for numZeros = 0; numZeros < len(b); numZeros++ {
|
||
|
if b[numZeros] != alphabetIdx0 {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
flen := numZeros + len(tmpval)
|
||
|
val := make([]byte, flen)
|
||
|
copy(val[numZeros:], tmpval)
|
||
|
|
||
|
return val
|
||
|
}
|
||
|
|
||
|
// Encode encodes a byte slice to a modified base58 string.
|
||
|
func Encode(b []byte) string {
|
||
|
x := new(big.Int)
|
||
|
x.SetBytes(b)
|
||
|
|
||
|
answer := make([]byte, 0, len(b)*136/100)
|
||
|
for x.Cmp(bigZero) > 0 {
|
||
|
mod := new(big.Int)
|
||
|
x.DivMod(x, bigRadix, mod)
|
||
|
answer = append(answer, alphabet[mod.Int64()])
|
||
|
}
|
||
|
|
||
|
// leading zero bytes
|
||
|
for _, i := range b {
|
||
|
if i != 0 {
|
||
|
break
|
||
|
}
|
||
|
answer = append(answer, alphabetIdx0)
|
||
|
}
|
||
|
|
||
|
// reverse
|
||
|
alen := len(answer)
|
||
|
for i := 0; i < alen/2; i++ {
|
||
|
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
|
||
|
}
|
||
|
|
||
|
return string(answer)
|
||
|
}
|