int b32_decode(unsigned char *buf, size_t *len) {
const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
- size_t i = 0;
- char x = 0, *ptr;
- unsigned char *output = buf, count, lsh;
- if(buf == NULL)
- return -1;
- for(count = 1;; count++) {
- while(isspace(buf[i]))
+ size_t i = 0, used = 0;
+ unsigned char x, *output = buf;
+ char *ptr;
+ for(;;) {
+ while(isspace(buf[i]) || buf[i] == '\n')
i++;
- if(buf[i] == '\0')
+ if(buf[i] == '\0' || buf[i] == '=')
break;
ptr = strchr(alphabet, toupper(buf[i++]));
if(ptr == NULL || *ptr == '\0')
return -1;
x = ptr - alphabet;
- if(x < 0)
- return -1;
- lsh = (count * 3) % 8;
- if(lsh > 3)
- *output |= x >> (8 - lsh);
- if(lsh + (count > 1) > 3)
+ switch(used++ % 8) {
+ case 0:
+ *output = x << 3;
+ break;
+ case 1:
+ *output |= x >> 2;
+ output++;
+ *output = x << 6;
+ break;
+ case 2:
+ *output |= x << 1;
+ break;
+ case 3:
+ *output |= x >> 4;
+ output++;
+ *output = x << 4;
+ break;
+ case 4:
+ *output |= x >> 1;
+ output++;
+ *output = x << 7;
+ break;
+ case 5:
+ *output |= x << 2;
+ break;
+ case 6:
+ *output |= x >> 3;
output++;
- *output = (x << lsh) | ((lsh < 3) * *output);
+ *output = x << 5;
+ break;
+ case 7:
+ *output |= x;
+ output++;
+ break;
+ }
}
if(len != NULL)
- *len = output - buf + 1;
+ *len = output - buf;
return 0;
}