Skip to content

Commit 77580f4

Browse files
committed
优化
1 parent 6e4edf0 commit 77580f4

8 files changed

Lines changed: 586 additions & 84 deletions

File tree

base58/alphabet.go

Lines changed: 0 additions & 42 deletions
This file was deleted.

base58/base58.go

Lines changed: 112 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package base58
22

33
import (
4+
"errors"
45
"math/big"
56
)
67

@@ -20,54 +21,53 @@ var bigRadix = [...]*big.Int{
2021

2122
var bigRadix10 = big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58) // 58^10
2223

23-
// 解析
24-
func Decode(b string) []byte {
25-
answer := big.NewInt(0)
26-
scratch := new(big.Int)
24+
const (
25+
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
2726

28-
for t := b; len(t) > 0; {
29-
n := len(t)
30-
if n > 10 {
31-
n = 10
32-
}
27+
alphabetIdx0 = '1'
28+
)
3329

34-
total := uint64(0)
35-
for _, v := range t[:n] {
36-
tmp := b58[v]
37-
if tmp == 255 {
38-
return []byte("")
39-
}
40-
total = total*58 + uint64(tmp)
41-
}
30+
var StdEncoding = NewEncoding(alphabet)
4231

43-
answer.Mul(answer, bigRadix[n])
44-
scratch.SetUint64(total)
45-
answer.Add(answer, scratch)
32+
// An Encoding is a base 58 encoding/decoding scheme defined by a 58-character alphabet.
33+
type Encoding struct {
34+
encode [58]byte
35+
decodeMap [256]byte
36+
}
4637

47-
t = t[n:]
38+
// NewEncoding returns a new Encoding defined by the given alphabet, which must
39+
// be a 58-byte string that does not contain CR or LF ('\r', '\n').
40+
func NewEncoding(encoder string) *Encoding {
41+
if len(encoder) != 58 {
42+
panic("base58: encoding alphabet is not 58 bytes long")
4843
}
4944

50-
tmpval := answer.Bytes()
51-
52-
var numZeros int
53-
for numZeros = 0; numZeros < len(b); numZeros++ {
54-
if b[numZeros] != alphabetIdx0 {
55-
break
45+
for i := 0; i < len(encoder); i++ {
46+
if encoder[i] == '\n' || encoder[i] == '\r' {
47+
panic("base58: encoding alphabet contains newline character")
5648
}
5749
}
58-
flen := numZeros + len(tmpval)
59-
val := make([]byte, flen)
60-
copy(val[numZeros:], tmpval)
6150

62-
return val
51+
e := new(Encoding)
52+
copy(e.encode[:], encoder)
53+
54+
for i := 0; i < len(e.decodeMap); i++ {
55+
// 0xff indicates that this entry in the decode map is not in the encoding alphabet.
56+
e.decodeMap[i] = 0xff
57+
}
58+
59+
for i := 0; i < len(encoder); i++ {
60+
e.decodeMap[encoder[i]] = byte(i)
61+
}
62+
63+
return e
6364
}
6465

65-
// 编码
66-
func Encode(b []byte) string {
66+
func (enc *Encoding) Encode(b []byte) []byte {
6767
x := new(big.Int)
6868
x.SetBytes(b)
6969

70-
maxlen := int(float64(len(b))*1.365658237309761) + 1
70+
maxlen := enc.EncodedLen(len(b))
7171
answer := make([]byte, 0, maxlen)
7272
mod := new(big.Int)
7373

@@ -76,13 +76,13 @@ func Encode(b []byte) string {
7676
if x.Sign() == 0 {
7777
m := mod.Int64()
7878
for m > 0 {
79-
answer = append(answer, alphabet[m%58])
79+
answer = append(answer, enc.encode[m%58])
8080
m /= 58
8181
}
8282
} else {
8383
m := mod.Int64()
8484
for i := 0; i < 10; i++ {
85-
answer = append(answer, alphabet[m%58])
85+
answer = append(answer, enc.encode[m%58])
8686
m /= 58
8787
}
8888
}
@@ -101,5 +101,81 @@ func Encode(b []byte) string {
101101
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
102102
}
103103

104+
return answer
105+
}
106+
107+
// EncodeToString returns the base58 encoding of src.
108+
func (enc *Encoding) EncodeToString(src []byte) string {
109+
answer := enc.Encode(src)
110+
104111
return string(answer)
105112
}
113+
114+
// EncodedLen returns an upper bound on the length in bytes of the base58 encoding
115+
// of an input buffer of length n. The true encoded length may be shorter.
116+
func (enc *Encoding) EncodedLen(n int) int {
117+
return int(float64(n)*1.365658237309761) + 1
118+
}
119+
120+
// Decode decodes src using the encoding enc. It writes at most DecodedLen(len(src))
121+
// bytes to dst and returns the number of bytes written. If src contains invalid base58
122+
// data, it will return the number of bytes successfully written and CorruptInputError.
123+
func (enc *Encoding) Decode(src []byte) ([]byte, error) {
124+
answer := big.NewInt(0)
125+
scratch := new(big.Int)
126+
127+
b := string(src)
128+
129+
for t := b; len(t) > 0; {
130+
n := len(t)
131+
if n > 10 {
132+
n = 10
133+
}
134+
135+
total := uint64(0)
136+
for _, v := range t[:n] {
137+
if v > 255 {
138+
return []byte(""), errors.New("base58: src data error")
139+
}
140+
141+
tmp := enc.decodeMap[v]
142+
if tmp == 255 {
143+
return []byte(""), errors.New("base58: src data error")
144+
}
145+
146+
total = total*58 + uint64(tmp)
147+
}
148+
149+
answer.Mul(answer, bigRadix[n])
150+
scratch.SetUint64(total)
151+
answer.Add(answer, scratch)
152+
153+
t = t[n:]
154+
}
155+
156+
tmpval := answer.Bytes()
157+
158+
var numZeros int
159+
for numZeros = 0; numZeros < len(b); numZeros++ {
160+
if b[numZeros] != alphabetIdx0 {
161+
break
162+
}
163+
}
164+
165+
flen := numZeros + len(tmpval)
166+
val := make([]byte, flen)
167+
copy(val[numZeros:], tmpval)
168+
169+
return val, nil
170+
}
171+
172+
// DecodeString returns the bytes represented by the base58 string s.
173+
func (enc *Encoding) DecodeString(src string) ([]byte, error) {
174+
return enc.Decode([]byte(src))
175+
}
176+
177+
// DecodedLen returns the maximum length in bytes of the decoded data
178+
// corresponding to n bytes of base58-encoded data.
179+
func (enc *Encoding) DecodedLen(n int) int {
180+
return int((float64(n) - 1) / 1.365658237309761)
181+
}

0 commit comments

Comments
 (0)