1
2
3
4
5
6 package base32
7
8 import (
9 "io"
10 "math"
11 "slices"
12 "strconv"
13 )
14
15
18
19
20
21
22
23 type Encoding struct {
24 encode [32]byte
25 decodeMap [256]uint8
26 padChar rune
27 }
28
29 const (
30 StdPadding rune = '='
31 NoPadding rune = -1
32 )
33
34 const (
35 decodeMapInitialize = "" +
36 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
37 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
38 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
39 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
40 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
41 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
42 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
43 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
44 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
45 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
46 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
47 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
48 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
49 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
50 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
51 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
52 invalidIndex = '\xff'
53 )
54
55
56
57
58
59
60
61
62 func NewEncoding(encoder string) *Encoding {
63 if len(encoder) != 32 {
64 panic("encoding alphabet is not 32-bytes long")
65 }
66
67 e := new(Encoding)
68 e.padChar = StdPadding
69 copy(e.encode[:], encoder)
70 copy(e.decodeMap[:], decodeMapInitialize)
71
72 for i := 0; i < len(encoder); i++ {
73
74
75
76 switch {
77 case encoder[i] == '\n' || encoder[i] == '\r':
78 panic("encoding alphabet contains newline character")
79 case e.decodeMap[encoder[i]] != invalidIndex:
80 panic("encoding alphabet includes duplicate symbols")
81 }
82 e.decodeMap[encoder[i]] = uint8(i)
83 }
84 return e
85 }
86
87
88 var StdEncoding = NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")
89
90
91
92 var HexEncoding = NewEncoding("0123456789ABCDEFGHIJKLMNOPQRSTUV")
93
94
95
96
97
98
99
100
101 func (enc Encoding) WithPadding(padding rune) *Encoding {
102 switch {
103 case padding < NoPadding || padding == '\r' || padding == '\n' || padding > 0xff:
104 panic("invalid padding")
105 case padding != NoPadding && enc.decodeMap[byte(padding)] != invalidIndex:
106 panic("padding contained in alphabet")
107 }
108 enc.padChar = padding
109 return &enc
110 }
111
112
115
116
117
118
119
120
121
122 func (enc *Encoding) Encode(dst, src []byte) {
123 if len(src) == 0 {
124 return
125 }
126
127
128
129 _ = enc.encode
130
131 for len(src) >= 5 {
132
133
134 hi := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
135 lo := hi<<8 | uint32(src[4])
136
137 _ = dst[7]
138 dst[0] = enc.encode[(hi>>27)&0x1F]
139 dst[1] = enc.encode[(hi>>22)&0x1F]
140 dst[2] = enc.encode[(hi>>17)&0x1F]
141 dst[3] = enc.encode[(hi>>12)&0x1F]
142 dst[4] = enc.encode[(hi>>7)&0x1F]
143 dst[5] = enc.encode[(hi>>2)&0x1F]
144 dst[6] = enc.encode[(lo>>5)&0x1F]
145 dst[7] = enc.encode[(lo)&0x1F]
146
147 src = src[5:]
148 dst = dst[8:]
149 }
150
151
152 if len(src) == 0 {
153 return
154 }
155
156
157 val := uint32(0)
158 switch len(src) {
159 case 4:
160 val |= uint32(src[3])
161 dst[6] = enc.encode[val<<3&0x1F]
162 dst[5] = enc.encode[val>>2&0x1F]
163 fallthrough
164 case 3:
165 val |= uint32(src[2]) << 8
166 dst[4] = enc.encode[val>>7&0x1F]
167 fallthrough
168 case 2:
169 val |= uint32(src[1]) << 16
170 dst[3] = enc.encode[val>>12&0x1F]
171 dst[2] = enc.encode[val>>17&0x1F]
172 fallthrough
173 case 1:
174 val |= uint32(src[0]) << 24
175 dst[1] = enc.encode[val>>22&0x1F]
176 dst[0] = enc.encode[val>>27&0x1F]
177 }
178
179
180 if enc.padChar != NoPadding {
181 nPad := (len(src) * 8 / 5) + 1
182 for i := nPad; i < 8; i++ {
183 dst[i] = byte(enc.padChar)
184 }
185 }
186 }
187
188
189
190 func (enc *Encoding) AppendEncode(dst, src []byte) []byte {
191 n := enc.EncodedLen(len(src))
192 dst = slices.Grow(dst, n)
193 enc.Encode(dst[len(dst):][:n], src)
194 return dst[:len(dst)+n]
195 }
196
197
198 func (enc *Encoding) EncodeToString(src []byte) string {
199 buf := make([]byte, enc.EncodedLen(len(src)))
200 enc.Encode(buf, src)
201 return string(buf)
202 }
203
204 type encoder struct {
205 err error
206 enc *Encoding
207 w io.Writer
208 buf [5]byte
209 nbuf int
210 out [1024]byte
211 }
212
213 func (e *encoder) Write(p []byte) (n int, err error) {
214 if e.err != nil {
215 return 0, e.err
216 }
217
218
219 if e.nbuf > 0 {
220 var i int
221 for i = 0; i < len(p) && e.nbuf < 5; i++ {
222 e.buf[e.nbuf] = p[i]
223 e.nbuf++
224 }
225 n += i
226 p = p[i:]
227 if e.nbuf < 5 {
228 return
229 }
230 e.enc.Encode(e.out[0:], e.buf[0:])
231 if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
232 return n, e.err
233 }
234 e.nbuf = 0
235 }
236
237
238 for len(p) >= 5 {
239 nn := len(e.out) / 8 * 5
240 if nn > len(p) {
241 nn = len(p)
242 nn -= nn % 5
243 }
244 e.enc.Encode(e.out[0:], p[0:nn])
245 if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
246 return n, e.err
247 }
248 n += nn
249 p = p[nn:]
250 }
251
252
253 copy(e.buf[:], p)
254 e.nbuf = len(p)
255 n += len(p)
256 return
257 }
258
259
260
261 func (e *encoder) Close() error {
262
263 if e.err == nil && e.nbuf > 0 {
264 e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
265 encodedLen := e.enc.EncodedLen(e.nbuf)
266 e.nbuf = 0
267 _, e.err = e.w.Write(e.out[0:encodedLen])
268 }
269 return e.err
270 }
271
272
273
274
275
276
277 func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
278 return &encoder{enc: enc, w: w}
279 }
280
281
282
283
284
285 func (enc *Encoding) EncodedLen(n int) int {
286 if enc.padChar == NoPadding {
287 if n > math.MaxInt/8*5+4 {
288 panic("encoded length overflows int")
289 }
290 return n/5*8 + (n%5*8+4)/5
291 }
292 if n > math.MaxInt/8*5 {
293 panic("encoded length overflows int")
294 }
295 return (n + 4) / 5 * 8
296 }
297
298
301
302 type CorruptInputError int64
303
304 func (e CorruptInputError) Error() string {
305 return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
306 }
307
308
309
310
311
312 func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
313
314 _ = enc.decodeMap
315
316 dsti := 0
317 olen := len(src)
318
319 for len(src) > 0 && !end {
320
321 var dbuf [8]byte
322 dlen := 8
323
324 for j := 0; j < 8; {
325
326 if len(src) == 0 {
327 if enc.padChar != NoPadding {
328
329 return n, false, CorruptInputError(olen - len(src) - j)
330 }
331
332 dlen, end = j, true
333 break
334 }
335 in := src[0]
336 src = src[1:]
337 if in == byte(enc.padChar) && j >= 2 && len(src) < 8 {
338
339 if len(src)+j < 8-1 {
340
341 return n, false, CorruptInputError(olen)
342 }
343 for k := 0; k < 8-1-j; k++ {
344 if len(src) > k && src[k] != byte(enc.padChar) {
345
346 return n, false, CorruptInputError(olen - len(src) + k - 1)
347 }
348 }
349 dlen, end = j, true
350
351
352
353
354
355 if dlen == 1 || dlen == 3 || dlen == 6 {
356 return n, false, CorruptInputError(olen - len(src) - 1)
357 }
358 break
359 }
360 dbuf[j] = enc.decodeMap[in]
361 if dbuf[j] == 0xFF {
362 return n, false, CorruptInputError(olen - len(src) - 1)
363 }
364 j++
365 }
366
367
368
369 switch dlen {
370 case 8:
371 dst[dsti+4] = dbuf[6]<<5 | dbuf[7]
372 n++
373 fallthrough
374 case 7:
375 dst[dsti+3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
376 n++
377 fallthrough
378 case 5:
379 dst[dsti+2] = dbuf[3]<<4 | dbuf[4]>>1
380 n++
381 fallthrough
382 case 4:
383 dst[dsti+1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
384 n++
385 fallthrough
386 case 2:
387 dst[dsti+0] = dbuf[0]<<3 | dbuf[1]>>2
388 n++
389 }
390 dsti += 5
391 }
392 return n, end, nil
393 }
394
395
396
397
398
399
400
401 func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
402 buf := make([]byte, len(src))
403 l := stripNewlines(buf, src)
404 n, _, err = enc.decode(dst, buf[:l])
405 return
406 }
407
408
409
410
411
412 func (enc *Encoding) AppendDecode(dst, src []byte) ([]byte, error) {
413
414 n := len(src)
415 for n > 0 && rune(src[n-1]) == enc.padChar {
416 n--
417 }
418 n = decodedLen(n, NoPadding)
419
420 dst = slices.Grow(dst, n)
421 n, err := enc.Decode(dst[len(dst):][:n], src)
422 return dst[:len(dst)+n], err
423 }
424
425
426
427
428 func (enc *Encoding) DecodeString(s string) ([]byte, error) {
429 buf := []byte(s)
430 l := stripNewlines(buf, buf)
431 n, _, err := enc.decode(buf, buf[:l])
432 return buf[:n], err
433 }
434
435 type decoder struct {
436 err error
437 enc *Encoding
438 r io.Reader
439 end bool
440 buf [1024]byte
441 nbuf int
442 out []byte
443 outbuf [1024 / 8 * 5]byte
444 }
445
446 func readEncodedData(r io.Reader, buf []byte, min int, expectsPadding bool) (n int, err error) {
447 for n < min && err == nil {
448 var nn int
449 nn, err = r.Read(buf[n:])
450 n += nn
451 }
452
453 if n < min && n > 0 && err == io.EOF {
454 err = io.ErrUnexpectedEOF
455 }
456
457
458
459 if expectsPadding && min < 8 && n == 0 && err == io.EOF {
460 err = io.ErrUnexpectedEOF
461 }
462 return
463 }
464
465 func (d *decoder) Read(p []byte) (n int, err error) {
466
467 if len(d.out) > 0 {
468 n = copy(p, d.out)
469 d.out = d.out[n:]
470 if len(d.out) == 0 {
471 return n, d.err
472 }
473 return n, nil
474 }
475
476 if d.err != nil {
477 return 0, d.err
478 }
479
480
481 nn := (len(p) + 4) / 5 * 8
482 if nn < 8 {
483 nn = 8
484 }
485 if nn > len(d.buf) {
486 nn = len(d.buf)
487 }
488
489
490 var min int
491 var expectsPadding bool
492 if d.enc.padChar == NoPadding {
493 min = 1
494 expectsPadding = false
495 } else {
496 min = 8 - d.nbuf
497 expectsPadding = true
498 }
499
500 nn, d.err = readEncodedData(d.r, d.buf[d.nbuf:nn], min, expectsPadding)
501 d.nbuf += nn
502 if d.nbuf < min {
503 return 0, d.err
504 }
505 if nn > 0 && d.end {
506 return 0, CorruptInputError(0)
507 }
508
509
510 var nr int
511 if d.enc.padChar == NoPadding {
512 nr = d.nbuf
513 } else {
514 nr = d.nbuf / 8 * 8
515 }
516 nw := d.enc.DecodedLen(d.nbuf)
517
518 if nw > len(p) {
519 nw, d.end, err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
520 d.out = d.outbuf[0:nw]
521 n = copy(p, d.out)
522 d.out = d.out[n:]
523 } else {
524 n, d.end, err = d.enc.decode(p, d.buf[0:nr])
525 }
526 d.nbuf -= nr
527 for i := 0; i < d.nbuf; i++ {
528 d.buf[i] = d.buf[i+nr]
529 }
530
531 if err != nil && (d.err == nil || d.err == io.EOF) {
532 d.err = err
533 }
534
535 if len(d.out) > 0 {
536
537
538
539
540 return n, nil
541 }
542
543 return n, d.err
544 }
545
546 type newlineFilteringReader struct {
547 wrapped io.Reader
548 }
549
550
551
552 func stripNewlines(dst, src []byte) int {
553 offset := 0
554 for _, b := range src {
555 if b == '\r' || b == '\n' {
556 continue
557 }
558 dst[offset] = b
559 offset++
560 }
561 return offset
562 }
563
564 func (r *newlineFilteringReader) Read(p []byte) (int, error) {
565 n, err := r.wrapped.Read(p)
566 for n > 0 {
567 s := p[0:n]
568 offset := stripNewlines(s, s)
569 if err != nil || offset > 0 {
570 return offset, err
571 }
572
573 n, err = r.wrapped.Read(p)
574 }
575 return n, err
576 }
577
578
579 func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
580 return &decoder{enc: enc, r: &newlineFilteringReader{r}}
581 }
582
583
584
585 func (enc *Encoding) DecodedLen(n int) int {
586 return decodedLen(n, enc.padChar)
587 }
588
589 func decodedLen(n int, padChar rune) int {
590 if padChar == NoPadding {
591 return n/8*5 + n%8*5/8
592 }
593 return n / 8 * 5
594 }
595
View as plain text