#include <stdlib.h>
#include <string.h>
#define between(x, min, max) ((x) >= (min) && (x) <= (max))
static inline unsigned int get_value(unsigned int src)
{
unsigned int ret;
if (between(src, 'A', 'Z'))
{
ret = src - 'A';
}
else if (between(src, 'a', 'z'))
{
ret = src - 'a' + 26;
}
else if (between(src, '0', '9'))
{
ret = src - '0' + 52;
}
else if (src == '+')
{
ret = 62;
}
else if (src == '/')
{
ret = 63;
}
else
{
ret = 0;
}
return ret;
}
unsigned int base64_decode(unsigned char **dest, const unsigned char *src)
{
unsigned char *p_dest;
const unsigned char *p_last;
unsigned int src_leng, dest_leng, counter;
src_leng = strlen((const char *) src);
counter = src_leng >> 2;
dest_leng = counter + (counter << 1);
p_last = src + src_leng;
if ('=' == *p_last)
{
--dest_leng;
}
if ('=' == *(p_last - 1))
{
--dest_leng;
}
p_dest = malloc(dest_leng);
*dest = p_dest;
while (counter--)
{
unsigned int t0, t1, t2, t3;
t0 = get_value(*src++);
t1 = get_value(*src++);
t2 = get_value(*src++);
t3 = get_value(*src++);
*p_dest++ = (t0 << 2 | t1 >> 4);
*p_dest++ = (t1 << 4 | t2 >> 2);
*p_dest++ = (t2 << 6 | t3);
}
return dest_leng;
}