03b01d2 |
Jamozed |
2022-03-06 17:10:01 |
0
|
// util/base32.c, version 1.0.4 |
c01a723 |
Jamozed |
2022-02-05 19:04:03 |
1
|
// Base32 source file from libutil |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
2
|
// Copyright (C) 2021, Jakob Wakeling |
03b01d2 |
Jamozed |
2022-03-06 17:10:01 |
3
|
// MIT Licence |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
4
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
5
|
#include "base32.h" |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
6
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
7
|
#include <stdint.h> |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
8
|
#include <stdlib.h> |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
9
|
#include <string.h> |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
10
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
11
|
static const uint8_t B32E[]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
12
|
static const uint8_t B32D[]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
13
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
14
|
/* Encode Base32 */ |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
15
|
size_t b32encode(uint8_t *dst, uint8_t *src, size_t len) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
16
|
register uint8_t *i = src, *o = dst; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
17
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
18
|
for (; len >= 5; len -= 5) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
19
|
*o++ = B32E[i[0] >> 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
20
|
*o++ = B32E[((i[0] & 0x07) << 2) | (i[1] >> 6)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
21
|
*o++ = B32E[(i[1] >> 1) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
22
|
*o++ = B32E[((i[1] & 0x01) << 4) | (i[2] >> 4)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
23
|
*o++ = B32E[((i[2] & 0x0F) << 1) | (i[3] >> 7)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
24
|
*o++ = B32E[(i[3] >> 2) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
25
|
*o++ = B32E[((i[3] & 0x03) << 3) | (i[4] >> 5)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
26
|
*o++ = B32E[i[4] & 0x1F]; i += 5; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
27
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
28
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
29
|
switch (len) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
30
|
case 1: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
31
|
*o++ = B32E[i[0] >> 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
32
|
*o++ = B32E[(i[0] & 0x07) << 2]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
33
|
memset(o, '=', 6); o += 6; break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
34
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
35
|
case 2: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
36
|
*o++ = B32E[i[0] >> 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
37
|
*o++ = B32E[((i[0] & 0x07) << 2) | (i[1] >> 6)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
38
|
*o++ = B32E[(i[1] >> 1) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
39
|
*o++ = B32E[(i[1] & 0x01) << 4]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
40
|
memset(o, '=', 4); o += 4; break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
41
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
42
|
case 3: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
43
|
*o++ = B32E[i[0] >> 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
44
|
*o++ = B32E[((i[0] & 0x07) << 2) | (i[1] >> 6)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
45
|
*o++ = B32E[(i[1] >> 1) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
46
|
*o++ = B32E[((i[1] & 0x01) << 4) | (i[2] >> 4)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
47
|
*o++ = B32E[(i[2] & 0x0F) << 1]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
48
|
memset(o, '=', 3); o += 3; break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
49
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
50
|
case 4: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
51
|
*o++ = B32E[i[0] >> 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
52
|
*o++ = B32E[((i[0] & 0x07) << 2) | (i[1] >> 6)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
53
|
*o++ = B32E[(i[1] >> 1) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
54
|
*o++ = B32E[((i[1] & 0x01) << 4) | (i[2] >> 4)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
55
|
*o++ = B32E[((i[2] & 0x0F) << 1) | (i[3] >> 7)]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
56
|
*o++ = B32E[(i[3] >> 2) & 0x1F]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
57
|
*o++ = B32E[(i[3] & 0x03) << 3]; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
58
|
*o++ = '='; break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
59
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
60
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
61
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
62
|
return o - dst; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
63
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
64
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
65
|
/* Decode Base32 */ |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
66
|
size_t b32decode(uint8_t *dst, uint8_t *src, size_t len) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
67
|
register uint8_t *i = src, *o = dst; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
68
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
69
|
for (; src[len - 1] == '='; --len); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
70
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
71
|
for (; len >= 8; len -= 8) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
72
|
*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
73
|
*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
74
|
*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
75
|
*o++ = (B32D[i[4]] << 7) | (B32D[i[5]] << 2) | (B32D[i[6]] >> 3); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
76
|
*o++ = (B32D[i[6]] << 5) | (B32D[i[7]]); i += 8; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
77
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
78
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
79
|
switch (len) { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
80
|
case 2: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
81
|
*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
82
|
*o++ = (B32D[i[1]] << 6); break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
83
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
84
|
case 4: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
85
|
*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
86
|
*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
87
|
*o++ = (B32D[i[3]] << 4); break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
88
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
89
|
case 5: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
90
|
*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
91
|
*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
92
|
*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
93
|
*o++ = (B32D[i[4]] << 7); break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
94
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
95
|
case 7: { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
96
|
*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
97
|
*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
98
|
*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
99
|
*o++ = (B32D[i[4]] << 7) | (B32D[i[5]] << 2) | (B32D[i[6]] >> 3); |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
100
|
*o++ = (B32D[i[6]] << 5); break; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
101
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
102
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
103
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
104
|
return o - dst; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
105
|
} |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
106
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
107
|
static const uint8_t B32E[] = { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
108
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
109
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
110
|
'2', '3', '4', '5', '6', '7' |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
111
|
}; |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
112
|
|
d079bad |
Jamozed |
2021-02-21 23:42:46 |
113
|
static const uint8_t B32D[] = { |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
114
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
115
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
116
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
117
|
0, 0, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
118
|
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
119
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 |
d079bad |
Jamozed |
2021-02-21 23:42:46 |
120
|
}; |
|
|
|
121
|
|