Skip to content

Commit 8432b74

Browse files
committed
优化
1 parent 77580f4 commit 8432b74

15 files changed

Lines changed: 317 additions & 281 deletions

File tree

base100/base100.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,6 @@ const (
1111
forth = 0x80
1212
)
1313

14-
// Encode tranforms bytes into base100 utf-8 encoded string
15-
func Encode(data []byte) string {
16-
result := make([]byte, len(data)*4)
17-
for i, b := range data {
18-
result[i*4+0] = first
19-
result[i*4+1] = second
20-
result[i*4+2] = byte((uint16(b)+shift)/divisor + third)
21-
result[i*4+3] = (b+shift)%divisor + forth
22-
}
23-
return string(result)
24-
}
25-
2614
// InvalidInputError is returned when Decode fails
2715
type InvalidInputError struct {
2816
message string
@@ -34,10 +22,23 @@ func (e InvalidInputError) Error() string {
3422

3523
// ErrInvalidLength is returned when length of string being decoded is
3624
// not divisible by four
37-
var ErrInvalidLength = InvalidInputError{"len(data) should be divisible by 4"}
25+
var ErrInvalidLength = InvalidInputError{"go-encoding/base100: len(data) should be divisible by 4"}
3826

3927
// ErrInvalidData is returned if data is not a valid base100 string
40-
var ErrInvalidData = InvalidInputError{"data is invalid"}
28+
var ErrInvalidData = InvalidInputError{"go-encoding/base100: data is invalid"}
29+
30+
// Encode tranforms bytes into base100 utf-8 encoded string
31+
func Encode(data []byte) string {
32+
result := make([]byte, len(data)*4)
33+
for i, b := range data {
34+
result[i*4+0] = first
35+
result[i*4+1] = second
36+
result[i*4+2] = byte((uint16(b)+shift)/divisor + third)
37+
result[i*4+3] = (b+shift)%divisor + forth
38+
}
39+
40+
return string(result)
41+
}
4142

4243
// Decode transforms base100 utf-8 encoded string into bytes
4344
func Decode(data string) ([]byte, error) {
@@ -54,5 +55,6 @@ func Decode(data string) ([]byte, error) {
5455
result[i/4] = (data[i+2]-third)*divisor +
5556
data[i+3] - forth - shift
5657
}
58+
5759
return result, nil
5860
}

base45/base45.go

Lines changed: 101 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package base45
22

33
import (
44
"fmt"
5+
"unsafe"
6+
"reflect"
57
"strings"
68
"encoding/binary"
79
)
@@ -18,7 +20,7 @@ type InvalidLengthError struct {
1820
}
1921

2022
func (e InvalidLengthError) Error() string {
21-
return fmt.Sprintf("invalid length n=%d. It should be n mod 3 = [0, 2] NOT n mod 3 = %d", e.length, e.mod)
23+
return fmt.Sprintf("go-encoding/base45: invalid length n=%d. It should be n mod 3 = [0, 2] NOT n mod 3 = %d", e.length, e.mod)
2224
}
2325

2426
type InvalidCharacterError struct {
@@ -27,15 +29,15 @@ type InvalidCharacterError struct {
2729
}
2830

2931
func (e InvalidCharacterError) Error() string {
30-
return fmt.Sprintf("invalid character %s at position: %d\n", string(e.char), e.position)
32+
return fmt.Sprintf("go-encoding/base45: invalid character %s at position: %d\n", string(e.char), e.position)
3133
}
3234

3335
type IllegalBase45ByteError struct {
3436
position int
3537
}
3638

3739
func (e IllegalBase45ByteError) Error() string {
38-
return fmt.Sprintf("illegal base45 data at byte position %d\n", e.position)
40+
return fmt.Sprintf("go-encoding/base45: illegal base45 data at byte position %d\n", e.position)
3941
}
4042

4143
// encodingMap
@@ -59,102 +61,53 @@ func (e IllegalBase45ByteError) Error() string {
5961
// 09 9 21 L 33 X
6062
// 10 A 22 M 34 Y
6163
// 11 B 23 N 35 Z
62-
var encodingMap = map[byte]rune {
63-
byte(0): '0',
64-
byte(1): '1',
65-
byte(2): '2',
66-
byte(3): '3',
67-
byte(4): '4',
68-
byte(5): '5',
69-
byte(6): '6',
70-
byte(7): '7',
71-
byte(8): '8',
72-
byte(9): '9',
73-
byte(10): 'A',
74-
byte(11): 'B',
75-
byte(12): 'C',
76-
byte(13): 'D',
77-
byte(14): 'E',
78-
byte(15): 'F',
79-
byte(16): 'G',
80-
byte(17): 'H',
81-
byte(18): 'I',
82-
byte(19): 'J',
83-
byte(20): 'K',
84-
byte(21): 'L',
85-
byte(22): 'M',
86-
byte(23): 'N',
87-
byte(24): 'O',
88-
byte(25): 'P',
89-
byte(26): 'Q',
90-
byte(27): 'R',
91-
byte(28): 'S',
92-
byte(29): 'T',
93-
byte(30): 'U',
94-
byte(31): 'V',
95-
byte(32): 'W',
96-
byte(33): 'X',
97-
byte(34): 'Y',
98-
byte(35): 'Z',
99-
byte(36): ' ',
100-
byte(37): '$',
101-
byte(38): '%',
102-
byte(39): '*',
103-
byte(40): '+',
104-
byte(41): '-',
105-
byte(42): '.',
106-
byte(43): '/',
107-
byte(44): ':',
64+
const encodeStd = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
65+
66+
// StdEncoding is the standard base62 encoding.
67+
var StdEncoding = NewEncoding(encodeStd)
68+
69+
/*
70+
* Encodings
71+
*/
72+
73+
// An Encoding is a radix 45 encoding/decoding scheme, defined by a 45-character alphabet.
74+
type Encoding struct {
75+
encode [45]byte
76+
decodeMap [256]byte
10877
}
10978

110-
var decodingMap = map[rune]byte{
111-
'0': byte(0),
112-
'1': byte(1),
113-
'2': byte(2),
114-
'3': byte(3),
115-
'4': byte(4),
116-
'5': byte(5),
117-
'6': byte(6),
118-
'7': byte(7),
119-
'8': byte(8),
120-
'9': byte(9),
121-
'A': byte(10),
122-
'B': byte(11),
123-
'C': byte(12),
124-
'D': byte(13),
125-
'E': byte(14),
126-
'F': byte(15),
127-
'G': byte(16),
128-
'H': byte(17),
129-
'I': byte(18),
130-
'J': byte(19),
131-
'K': byte(20),
132-
'L': byte(21),
133-
'M': byte(22),
134-
'N': byte(23),
135-
'O': byte(24),
136-
'P': byte(25),
137-
'Q': byte(26),
138-
'R': byte(27),
139-
'S': byte(28),
140-
'T': byte(29),
141-
'U': byte(30),
142-
'V': byte(31),
143-
'W': byte(32),
144-
'X': byte(33),
145-
'Y': byte(34),
146-
'Z': byte(35),
147-
' ': byte(36),
148-
'$': byte(37),
149-
'%': byte(38),
150-
'*': byte(39),
151-
'+': byte(40),
152-
'-': byte(41),
153-
'.': byte(42),
154-
'/': byte(43),
155-
':': byte(44),
79+
// NewEncoding returns a new padded Encoding defined by the given alphabet,
80+
// which must be a 45-byte string that does not contain the padding character
81+
// or CR / LF ('\r', '\n').
82+
func NewEncoding(encoder string) *Encoding {
83+
if len(encoder) != 45 {
84+
panic("go-encoding/base45: encoding alphabet is not 45-bytes long")
85+
}
86+
87+
for i := 0; i < len(encoder); i++ {
88+
if encoder[i] == '\n' || encoder[i] == '\r' {
89+
panic("go-encoding/base45: encoding alphabet contains newline character")
90+
}
91+
}
92+
93+
e := new(Encoding)
94+
copy(e.encode[:], encoder)
95+
96+
for i := 0; i < len(e.decodeMap); i++ {
97+
e.decodeMap[i] = 0xFF
98+
}
99+
100+
for i := 0; i < len(encoder); i++ {
101+
e.decodeMap[encoder[i]] = byte(i)
102+
}
103+
104+
return e
156105
}
157106

107+
/*
108+
* Encoder
109+
*/
110+
158111
// Encode
159112
// 4. The Base45 Encoding
160113
// A 45-character subset of US-ASCII is used; the 45 characters usable
@@ -188,68 +141,89 @@ var decodingMap = map[rune]byte{
188141
//
189142
// For decoding a Base45 encoded string the inverse operations are
190143
// performed.
191-
func Encode(in string) string {
192-
bytes := []byte(in)
144+
func (enc *Encoding) Encode(bytes []byte) []byte {
193145
pairs := encodePairs(bytes)
146+
194147
var builder strings.Builder
195148
for i, pair := range pairs {
196149
res := encodeBase45(pair)
197150
if i + 1 == len(pairs) && res[2] == 0 {
198151
for _, b := range res[:2] {
199-
if c, ok := encodingMap[b]; ok {
200-
builder.WriteRune(c)
152+
if len(enc.encode) > int(b) {
153+
builder.WriteByte(enc.encode[b])
201154
}
202155
}
203156
} else {
204157
for _, b := range res {
205-
if c, ok := encodingMap[b]; ok {
206-
builder.WriteRune(c)
158+
if len(enc.encode) > int(b) {
159+
builder.WriteByte(enc.encode[b])
207160
}
208161
}
209162
}
210163
}
211-
return builder.String()
164+
165+
return []byte(builder.String())
166+
}
167+
168+
// EncodeToString returns the base62 encoding of src.
169+
func (enc *Encoding) EncodeToString(src []byte) string {
170+
buf := enc.Encode(src)
171+
return string(buf)
212172
}
213173

174+
/*
175+
* Decoder
176+
*/
177+
214178
// Decode
215179
// Decoding example 1: The string "QED8WEX0" represents, when looked up
216180
// in Table 1, the values [26 14 13 8 32 14 33 0]. We arrange the
217181
// numbers in chunks of three, except for the last one which can be two,
218182
// and get [[26 14 13] [8 32 14] [33 0]]. In base 45 we get [26981
219183
// 29798 33] where the bytes are [[105 101] [116 102] [33]]. If we look
220184
// at the ASCII values we get the string "ietf!".
221-
func Decode(in string) (string, error) {
185+
func (enc *Encoding) Decode(in []byte) ([]byte, error) {
222186
size := len(in)
187+
223188
mod := size % 3
224189
if mod != 0 && mod != 2 {
225-
return "", InvalidLengthError{
190+
return nil, InvalidLengthError{
226191
length: size,
227192
mod: mod,
228193
}
229194
}
195+
230196
bytes := make([]byte, 0, size)
231197
for pos, char := range in {
232-
v, ok := decodingMap[char]
233-
if !ok {
234-
return "", InvalidCharacterError{
235-
char: char,
236-
position: pos,
198+
if len(enc.decodeMap) > int(char) {
199+
v := enc.decodeMap[char]
200+
201+
if int(v) == 255 {
202+
return nil, InvalidCharacterError{
203+
char: rune(char),
204+
position: pos,
205+
}
237206
}
207+
208+
bytes = append(bytes, v)
238209
}
239-
bytes = append(bytes, v)
240210
}
211+
241212
chunks := decodeChunks(bytes)
242213
triplets, err := decodeTriplets(chunks)
243214
if err != nil {
244-
return "", err
215+
return nil, err
245216
}
217+
246218
tripletsLength := len(triplets)
247219
decoded := make([]byte, 0, tripletsLength * 2)
220+
248221
for i := 0; i < tripletsLength - 1; i++ {
249222
bytes := uint16ToBytes(triplets[i])
250223
decoded = append(decoded, bytes[0])
251224
decoded = append(decoded, bytes[1])
252225
}
226+
253227
if mod == 2 {
254228
bytes := uint16ToBytes(triplets[tripletsLength - 1])
255229
decoded = append(decoded, bytes[1])
@@ -258,7 +232,15 @@ func Decode(in string) (string, error) {
258232
decoded = append(decoded, bytes[0])
259233
decoded = append(decoded, bytes[1])
260234
}
261-
return string(decoded), nil
235+
236+
return decoded, nil
237+
}
238+
239+
// DecodeString returns the bytes represented by the base62 string s.
240+
func (enc *Encoding) DecodeString(s string) ([]byte, error) {
241+
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
242+
bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
243+
return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
262244
}
263245

264246
func uint16ToBytes(in uint16) []byte {
@@ -297,8 +279,10 @@ func encodePairs(in []byte) [][]byte {
297279
} else {
298280
low = in[i]
299281
}
282+
300283
ret = append(ret, []byte{high, low})
301284
}
285+
302286
return ret
303287
}
304288

@@ -313,18 +297,22 @@ func encodeBase45(in []byte) []byte {
313297
func decodeTriplets(in [][]byte) ([]uint16, error) {
314298
size := len(in)
315299
ret := make([]uint16, 0, size)
300+
316301
for pos, chunk := range in {
317302
if len(chunk) == 3 {
318303
// n = c + (d*45) + (e*45*45)
319304
c := int(chunk[0])
320305
d := int(chunk[1])
321306
e := int(chunk[2])
322307
n := c + (d * base) + (e * baseSquare)
308+
323309
if n > maxUint16 {
324310
return nil, IllegalBase45ByteError{position: pos}
325311
}
312+
326313
ret = append(ret, uint16(n))
327314
}
315+
328316
if len(chunk) == 2 {
329317
// n = c + (d*45)
330318
c := uint16(chunk[0])
@@ -333,5 +321,6 @@ func decodeTriplets(in [][]byte) ([]uint16, error) {
333321
ret = append(ret, n)
334322
}
335323
}
324+
336325
return ret, nil
337326
}

0 commit comments

Comments
 (0)