Skip to content

Instantly share code, notes, and snippets.

@pyropeter
Created September 2, 2010 19:28
Show Gist options
  • Save pyropeter/562801 to your computer and use it in GitHub Desktop.
Save pyropeter/562801 to your computer and use it in GitHub Desktop.
base64 de/encode in C
static const char b64[] = "\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789+/";
static const unsigned char b64dec[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x00
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, //0x20
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, //0x30
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //0x40
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, //0x50
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //0x60
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, //0x70
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x80
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x90
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0xa0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0xb0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0xc0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0xd0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0xe0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //0xf0
};
char * base64Encode(char *data, int len) {
int blocks = (len + 2) / 3;
int newlen = blocks * 4 + 1;
char *result = malloc(newlen);
char *resptr = result;
int i;
for (i = len / 3 ; i > 0 ; i--) {
resptr[0] = b64[ (unsigned char)data[0] >> 2 ];
resptr[1] = b64[ ((unsigned char)data[0] & 0b11) << 4
| (unsigned char)data[1] >> 4 ];
resptr[2] = b64[ ((unsigned char)data[1] & 0b1111) << 2
| (unsigned char)data[2] >> 6 ];
resptr[3] = b64[ (unsigned char)data[2] & 0b111111 ];
resptr += 4;
data += 3;
}
if (len < blocks * 3 - 1) {
resptr[0] = b64[ (unsigned char)data[0] >> 2 ];
resptr[1] = b64[ ((unsigned char)data[0] & 0b11) << 4 ];
resptr[2] = '=';
resptr[3] = '=';
resptr += 4;
} else if (len < blocks * 3) {
resptr[0] = b64[ (unsigned char)data[0] >> 2 ];
resptr[1] = b64[ ((unsigned char)data[0] & 0b11) << 4
| (unsigned char)data[1] >> 4 ];
resptr[2] = b64[ ((unsigned char)data[1] & 0b1111) << 2 ];
resptr[3] = '=';
resptr += 4;
}
*resptr = 0;
return result;
}
char * base64Decode(char *text, int *outlen) {
// this functions treats invalid characters as 'A'. deal with it :-P
int inlen = (strlen(text) >> 2) << 2;
int blocks = inlen >> 2;
*outlen = blocks * 3 - (text[inlen-2] == '='
? 2 : (text[inlen-1] == '=' ? 1 : 0));
char *result = malloc(blocks * 3);
char *resptr = result;
int i;
for (i = 0 ; i < blocks ; i++) {
resptr[0] = b64dec[text[0]] << 2 | b64dec[text[1]] >> 4;
resptr[1] = b64dec[text[1]] << 4 | b64dec[text[2]] >> 2;
resptr[2] = b64dec[text[2]] << 6 | b64dec[text[3]];
text += 4;
resptr += 3;
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment