2014-01-09 06:46:05 +01:00
|
|
|
// Copyright (c) 2013-2014 Conformal Systems LLC.
|
2013-06-13 19:09:51 +02:00
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
2013-06-13 17:12:22 +02:00
|
|
|
|
|
|
|
package btcutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2013-08-06 19:40:08 +02:00
|
|
|
// alphabet is the modified base58 alphabet used by Bitcoin.
|
2013-06-13 17:12:22 +02:00
|
|
|
const alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
|
|
|
|
|
|
var bigRadix = big.NewInt(58)
|
|
|
|
var bigZero = big.NewInt(0)
|
|
|
|
|
2013-08-06 19:40:08 +02:00
|
|
|
// Base58Decode decodes a modified base58 string to a byte slice.
|
2013-06-13 17:12:22 +02:00
|
|
|
func Base58Decode(b string) []byte {
|
|
|
|
answer := big.NewInt(0)
|
|
|
|
j := big.NewInt(1)
|
|
|
|
|
|
|
|
for i := len(b) - 1; i >= 0; i-- {
|
|
|
|
tmp := strings.IndexAny(alphabet, string(b[i]))
|
|
|
|
if tmp == -1 {
|
|
|
|
return []byte("")
|
|
|
|
}
|
|
|
|
idx := big.NewInt(int64(tmp))
|
|
|
|
tmp1 := big.NewInt(0)
|
|
|
|
tmp1.Mul(j, idx)
|
|
|
|
|
|
|
|
answer.Add(answer, tmp1)
|
|
|
|
j.Mul(j, bigRadix)
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpval := answer.Bytes()
|
|
|
|
|
|
|
|
var numZeros int
|
|
|
|
for numZeros = 0; numZeros < len(b); numZeros++ {
|
|
|
|
if b[numZeros] != alphabet[0] {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
flen := numZeros + len(tmpval)
|
|
|
|
val := make([]byte, flen, flen)
|
|
|
|
copy(val[numZeros:], tmpval)
|
|
|
|
|
|
|
|
return val
|
|
|
|
}
|
|
|
|
|
2013-08-06 19:40:08 +02:00
|
|
|
// Base58Encode encodes a byte slice to a modified base58 string.
|
2013-06-13 17:12:22 +02:00
|
|
|
func Base58Encode(b []byte) string {
|
|
|
|
x := new(big.Int)
|
|
|
|
x.SetBytes(b)
|
|
|
|
|
2014-04-17 02:43:01 +02:00
|
|
|
answer := make([]byte, 0, len(b)*136/100)
|
2013-06-13 17:12:22 +02:00
|
|
|
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, alphabet[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|