base58.go raw
1 package base58
2
3 import (
4 "math/big"
5 )
6
7 var bigRadix = big.NewInt(58)
8 var bigZero = big.NewInt(0)
9
10 // Decode decodes a modified base58 string to a byte slice.
11 func Decode(b string) []byte {
12 answer := big.NewInt(0)
13 j := big.NewInt(1)
14 scratch := new(big.Int)
15 for i := len(b) - 1; i >= 0; i-- {
16 tmp := b58[b[i]]
17 if tmp == 255 {
18 return []byte("")
19 }
20 scratch.SetInt64(int64(tmp))
21 scratch.Mul(j, scratch)
22 answer.Add(answer, scratch)
23 j.Mul(j, bigRadix)
24 }
25 tmpval := answer.Bytes()
26 var numZeros int
27 for numZeros = 0; numZeros < len(b); numZeros++ {
28 if b[numZeros] != alphabetIdx0 {
29 break
30 }
31 }
32 flen := numZeros + len(tmpval)
33 val := make([]byte, flen)
34 copy(val[numZeros:], tmpval)
35 return val
36 }
37
38 // Encode encodes a byte slice to a modified base58 string.
39 func Encode(b []byte) string {
40 x := new(big.Int)
41 x.SetBytes(b)
42 answer := make([]byte, 0, len(b)*136/100)
43 for x.Cmp(bigZero) > 0 {
44 mod := new(big.Int)
45 x.DivMod(x, bigRadix, mod)
46 answer = append(answer, alphabet[mod.Int64()])
47 }
48 // leading zero bytes
49 for _, i := range b {
50 if i != 0 {
51 break
52 }
53 answer = append(answer, alphabetIdx0)
54 }
55 // reverse
56 alen := len(answer)
57 for i := 0; i < alen/2; i++ {
58 answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
59 }
60 return string(answer)
61 }
62