#include "error.h" #include "stralloc.h" #include "base32.h" static const unsigned char base32values[256] = { 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, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 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, 0x0a, 0x0b, 0x0c, 0xff, 0x0d, 0x0e, 0x0f, 0xff, 0x10, 0x11, 0x12, 0x13, 0x14, 0xff, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 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, 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, 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 }; int base32_decode(stralloc *out, const unsigned char *in, unsigned int inlen){ unsigned int i,v=0, vbits=0; unsigned char uch; char ch; if (!stralloc_copys(out,"")) return -1; for(i = 0; i < inlen; ++i){ uch = base32values[in[i]]; if (uch > 0x1f) {errno = error_proto; out->len = 0; return 0;} v |= uch << vbits; vbits += 5; if (vbits >= 8){ ch = v; if (!stralloc_append(out, &ch)) {out->len = 0; return -1;} vbits -= 8; v >>= 8; } } if (vbits){ ch = v; if (!stralloc_append(out, &ch)) {out->len = 0;return -1;} } return 1; } static const char hexchars[]="0123456789abcdef"; int base32_decodehex(stralloc *out, const unsigned char *in, unsigned int inlen){ unsigned int i,v=0, vbits=0; unsigned char uch; unsigned char ch; if (!stralloc_copys(out,"")) return -1; for(i = 0; i < inlen; ++i){ uch = base32values[in[i]]; if (uch > 0x1f) {errno = error_proto; out->len = 0; return 0;} v |= uch << vbits; vbits += 5; if (vbits >= 8){ ch = v; if (!stralloc_catb(out, hexchars + (ch >> 4), 1)) {out->len = 0; return -1;} if (!stralloc_catb(out, hexchars + (ch & 15), 1)) {out->len = 0; return -1;} vbits -= 8; v >>= 8; } } if (vbits){ ch = v; if (!stralloc_catb(out, hexchars + (ch >> 4), 1)) {out->len = 0; return -1;} if (!stralloc_catb(out, hexchars + (ch & 15), 1)) {out->len = 0; return -1;} } return 1; } static const char base32chars[] = "0123456789bcdfghjklmnpqrstuvwxyz"; int base32_encode(stralloc *out, const unsigned char *in, unsigned int inlen){ unsigned int j=0,v=0,bits=0; char ch; if (!stralloc_copys(out,"")) return -1; while (j < inlen){ v |= in[j++] << bits; bits += 8; while (bits >= 5){ ch = base32chars[v & 31]; if (!stralloc_append(out, &ch)) {out->len = 0;return -1;} bits -= 5; v >>= 5; } } if (bits){ ch = base32chars[v & 31]; if (!stralloc_append(out, &ch)) {out->len = 0;return -1;} bits -= 5; v >>= 5; } return 1; }