I'm trying to create a simple HTTP client. In order to make one that is standard compliant, I must be able to extract user information from a URI and convert it to base64 and send it via an authentication header to the server. I created this demo program to test my progress on this function I've made. Does this program seem sufficient? Is there any major flaws with it? You can see the demo here.
char *base64encode(char *input) {
int len = strlen(input), padding = (len % 3)?3 - (len % 3):0, n, xlen = 0;
size_t bitlen = len * 8;
uint8_t *x = malloc(((int)(bitlen / 24) * 4) + ((padding)?4:0)), i, o;
for (n = 0; n < len; n++) {
switch (n % 3) {
case 0:
i = (uint8_t)(input[n] >> 2);
x[xlen++] = i;
break;
case 1:
i = (uint8_t)((input[n-1] & 3) << 4);
o = (uint8_t)((input[n] & 240) >> 4);
x[xlen++] = i | o;
break;
case 2:
i = (uint8_t)((input[n-1] & 15) << 2);
o = (uint8_t)((input[n] & 192) >> 6);
x[xlen++] = i | o;
i = (uint8_t)(input[n] & 63);
x[xlen++] = i;
break;
}
if ((len - n) == ((padding==2)?2:3) && padding > 0) {
n++;
break;
}
}
if (padding == 2) {
i = (uint8_t)(input[n] >> 2);
x[xlen++] = i;
i = (uint8_t)((input[n] & 3) << 4);
x[xlen++] = i;
} else if (padding == 1) {
i = (uint8_t)(input[n] >> 2);
x[xlen++] = i;
i = (uint8_t)((input[n] & 3) << 4);
o = (uint8_t)((input[n+1] & 240) >> 4);
x[xlen++] = i | o;
i = (uint8_t)((input[n+1] & 15) << 2);
x[xlen++] = i;
}
const char *index = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *returnString = malloc((int)((bitlen / 24) + padding) * 4 + 1);
for (n = 0; n < ((int)(bitlen / 24) * 4) + ((padding)?4:0) - padding; n++) {
returnString[n] = index[x[n]];
}
free(x);
for (;padding > 0; padding--) {
returnString[n++] = '=';
}
returnString[n] = '\0';
return returnString;
}