#include <stdint.h>
/**
* Inspired by the base32 implementation here:
*
* https://sourceforge.net/p/cyoencode/code/HEAD/tree/trunk/src/CyoDecode.c
*
* Basically, the idea is to allocate a much too large array, fill it with 0xff
* and plug in the values from the alphabet in their corresponding holes.
*/
static uint8_t BASE32[0x80] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
void
base32_decode_hash(uint8_t *dst, char const *in)
{
int i, r, off;
uint8_t v[8];
for (r = 0; r < 6; r++) {
off = 8 * r;
for (i = 0; i < 8; i++)
v[i] = BASE32[(int)in[off + i]];
off = 5 * r;
dst[off] = v[0] << 3 | v[1] >> 2;
dst[off+1] = v[1] << 6 | v[2] << 1 | v[3] >> 4;
dst[off+2] = v[3] << 4 | v[4] >> 1;
dst[off+3] = v[4] << 7 | v[5] << 2 | v[6] >> 3;
dst[off+4] = v[6] << 5 | v[7];
}
/* decode the remaining two bytes */
off = 48; /* 6×8 */
for (i = 0; i < 5; i++)
v[i] = BASE32[(int)in[off+i]];
off = 30; /* 6×5 */
dst[off] = v[0] << 3 | v[1] >> 2;
dst[off+1] = v[1] << 6 | v[2] << 1 | v[3] >> 4;
}