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