1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#include <assert.h>
#include "base32.h"
#include "common.h"
static inline bool b32blktoa(uint8_t *restrict, const uint8_t *restrict)
__attribute__((always_inline));
static const uint8_t lookup[] = {
/* [00…07] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [08…0F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [10…17] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [18…1F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [20…27] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [28…2F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [30…37] = */ 0xFF, 0xFF, 26, 27, 28, 29, 30, 31,
/* [38…3F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF,
/* [40…47] = */ 0xFF, 0, 1, 2, 3, 4, 5, 6,
/* [48…4F] = */ 7, 8, 9, 10, 11, 12, 13, 14,
/* [50…57] = */ 15, 16, 17, 18, 19, 20, 21, 22,
/* [58…5F] = */ 23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [60…67] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [68…6F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [70…77] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [78…7F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [80…87] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [88…8F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [90…97] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [98…9F] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [A0…A7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [A8…AF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [B0…B7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [B8…BF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [C0…C7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [C8…CF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [D0…D7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [D8…DF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [E0…E7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [E8…EF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [F0…F7] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* [F8…FF] = */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
bool
b32toa(uint8_t *restrict dst, const char *restrict src, size_t len)
{
assert(len != 0);
size_t i, j;
for (i = j = 0; len - i >= 8; i += 8, j += 5) {
uint8_t bits[] = {
lookup[(uint8_t)src[i + 0]],
lookup[(uint8_t)src[i + 1]],
lookup[(uint8_t)src[i + 2]],
lookup[(uint8_t)src[i + 3]],
lookup[(uint8_t)src[i + 4]],
lookup[(uint8_t)src[i + 5]],
lookup[(uint8_t)src[i + 6]],
lookup[(uint8_t)src[i + 7]],
};
if (!b32blktoa(dst + j, bits))
return false;
}
uint8_t bits[8] = {0};
switch (len - i) {
case 7: bits[6] = lookup[(uint8_t)src[i + 6]]; /* fallthrough */
case 6: bits[5] = lookup[(uint8_t)src[i + 5]]; /* fallthrough */
case 5: bits[4] = lookup[(uint8_t)src[i + 4]]; /* fallthrough */
case 4: bits[3] = lookup[(uint8_t)src[i + 3]]; /* fallthrough */
case 3: bits[2] = lookup[(uint8_t)src[i + 2]]; /* fallthrough */
case 2: bits[1] = lookup[(uint8_t)src[i + 1]]; /* fallthrough */
case 1: bits[0] = lookup[(uint8_t)src[i + 0]];
return b32blktoa(dst + j, bits);
}
return true;
}
bool
b32blktoa(uint8_t *restrict dst, const uint8_t *restrict src)
{
uint8_t or = src[0] | src[1] | src[2] | src[3]
| src[4] | src[5] | src[6] | src[7];
if (or == 0xFF)
return false;
dst[0] = src[0]<<3 | src[1]>>2;
dst[1] = src[1]<<6 | src[2]<<1 | src[3]>>4;
dst[2] = src[3]<<4 | src[4]>>1;
dst[3] = src[4]<<7 | src[5]<<2 | src[6]>>3;
dst[4] = src[6]<<5 | src[7]>>0;
return true;
}
|