#include <stdio.h>
#include <stdlib.h> // malloc
#include <string.h>
#include <stdarg.h> // va_start, va_end
#define zmem(mem, n) memset(mem, 0, n)
#define STR_LEN 1024
static int b64enc_internal(const unsigned char *data, int len, char *dest)
{
/* base64 alphabet, taken from rfc3548 */
char *b64alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *buf = dest;
/* Encode three bytes per iteration a la rfc3548. */
while (len >= 3) {
buf[0] = b64alpha[(data[0] >> 2) & 0x3f];
buf[1] = b64alpha[((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0xf)];
buf[2] = b64alpha[((data[1] << 2) & 0x3c) | ((data[2] >> 6) & 0x3)];
buf[3] = b64alpha[data[2] & 0x3f];
data += 3;
buf += 4;
len -= 3;
}
/* Pad the remaining bytes. len is 0, 1, or 2 here. */
if (len > 0) {
buf[0] = b64alpha[(data[0] >> 2) & 0x3f];
if (len > 1) {
buf[1] = b64alpha[((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0xf)];
buf[2] = b64alpha[(data[1] << 2) & 0x3c];
} else {
buf[1] = b64alpha[(data[0] << 4) & 0x30];
buf[2] = '=';
}
buf[3] = '=';
buf += 4;
}
/*
* As mentioned in rfc3548, we need to be careful about
* how we null terminate and handle embedded null-termination.
*/
*buf = '\0';
return (buf - dest);
}
void fatal(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
fflush(stdout);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\nQUITTING!\n");
va_end(ap);
exit(1);
}
void *safe_malloc(size_t size) {
void *mymem;
if ((int)size < 0) /* Catch caller errors */
fatal("Tried to malloc negative amount of memory!!!");
mymem = malloc(size);
if (mymem == NULL)
fatal("Malloc Failed! Probably out of space.");
return mymem;
}
/* Take in plain text and encode into base64. */
char *b64enc(const unsigned char *data, int len)
{
char *dest;
/* malloc enough space to do something useful */
dest = (char *) safe_malloc(4 * len / 3 + 4);
dest[0] = '\0';
/* Call internal function to base64 encode data */
b64enc_internal(data, len, dest);
return (dest);
}
// https://c.runoob.com/front-end/693/
int main(int argc, char *argv[]) {
char s[STR_LEN];
char *t;
zmem(s, STR_LEN);
strcpy(s, "runoob");
t = b64enc(s, strlen(s));
fprintf(stdout, "%s\n", t); // cnVub29i
free(t);
return 0;
}