1 /* CC0 license (public domain) - see LICENSE file for details */
4 #include <ccan/endian/endian.h>
5 #include <string.h> /* for memcpy, memset */
7 const char *base32_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
11 * (1) The final quantum of encoding input is an integral multiple of 40
12 * bits; here, the final unit of encoded output will be an integral
13 * multiple of 8 characters with no "=" padding.
15 * (2) The final quantum of encoding input is exactly 8 bits; here, the
16 * final unit of encoded output will be two characters followed by
17 * six "=" padding characters.
19 * (3) The final quantum of encoding input is exactly 16 bits; here, the
20 * final unit of encoded output will be four characters followed by
21 * four "=" padding characters.
23 * (4) The final quantum of encoding input is exactly 24 bits; here, the
24 * final unit of encoded output will be five characters followed by
25 * three "=" padding characters.
27 * (5) The final quantum of encoding input is exactly 32 bits; here, the
28 * final unit of encoded output will be seven characters followed by
29 * one "=" padding character.
31 static size_t padlen(size_t remainder)
49 size_t base32_str_size(size_t bytes)
51 return (bytes + 4) / 5 * 8 + 1;
54 size_t base32_data_size(const char *str, size_t strlen)
56 /* 8 chars == 5 bytes, round up to avoid overflow even though
57 * not required for well-formed strings. */
58 size_t max = (strlen + 7) / 8 * 5, padding = 0;
60 /* Count trailing padding bytes. */
61 while (strlen && str[strlen-1] == base32_chars[32] && padding < 6) {
66 return max - (padding * 5 + 7) / 8;
69 static bool decode_8_chars(const char c[8], beint64_t *res, int *bytes)
74 for (i = 0; i < 8; i++) {
78 p = memchr(base32_chars, c[i], 32);
80 if (c[i] == base32_chars[32]) {
86 /* Can't have padding then non-pad */
89 acc |= (p - base32_chars);
91 *res = cpu_to_be64(acc);
93 /* Can't have 2 or 5 padding bytes */
94 if (num_pad == 5 || num_pad == 2)
96 *bytes = (40 - num_pad * 5) / 8;
100 bool base32_decode(const char *str, size_t slen, void *buf, size_t bufsize)
105 if (!decode_8_chars(str, &val, &bytes))
109 /* Copy bytes into dst. */
112 memcpy(buf, (char *)&val + 3, bytes);
113 buf = (char *)buf + bytes;
116 return slen == 0 && bufsize == 0;
119 static void encode_8_chars(char *dest, const uint8_t *buf, int bytes)
123 int bits = bytes * 8;
125 assert(bytes > 0 && bytes <= 5);
126 memcpy((char *)&val + 3, buf, bytes);
127 res = be64_to_cpu(val);
130 *dest = base32_chars[(res >> 35) & 0x1F];
137 memset(dest, base32_chars[32], padlen(bytes));
140 bool base32_encode(const void *buf, size_t bufsize, char *dest, size_t destsize)
150 encode_8_chars(dest, buf, bytes);
151 buf = (const char *)buf + bytes;