Skip to content

Instantly share code, notes, and snippets.

@FergusInLondon
Last active April 17, 2017 01:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FergusInLondon/47010962253e65d636fc98ebef74fad1 to your computer and use it in GitHub Desktop.
Save FergusInLondon/47010962253e65d636fc98ebef74fad1 to your computer and use it in GitHub Desktop.
Base 64 Encoding in C
#include <stdio.h>
#include <stdlib.h>
#define FIRST_SIX_INDEX (buf[0] & 0xfc) >> 2
#define SECOND_SIX_INDEX ((buf[0] & 0x03) << 4) + ((buf[1] & 0xf0) >> 4)
#define THIRD_SIX_INDEX ((buf[1] & 0x0f) << 2) + ((buf[2] & 0xc0) >> 6)
#define FOURTH_SIX_INDEX buf[2] & 0x3f
char base64_map[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char *
base64_encode(const unsigned char *src, size_t len) {
char *encoded = malloc( ((len/3) * 4) + 1);
int encoded_counter = 0, cursor = 0;
unsigned char buf[3];
/* Process the string 3 bytes at a time, allowing us to generate the
corresponding 4 6-bit values for the base64 representation */
for (; (cursor+3) < len; cursor += 3) {
// Buffer 3 bytes
buf[0] = *(src + cursor );
buf[1] = *(src + (cursor + 1) );
buf[2] = *(src + (cursor + 2) );
// Use bitmask macros to find the corresponding value in the base64 map
encoded[encoded_counter++] = base64_map[ FIRST_SIX_INDEX ];
encoded[encoded_counter++] = base64_map[ SECOND_SIX_INDEX ];
encoded[encoded_counter++] = base64_map[ THIRD_SIX_INDEX ];
encoded[encoded_counter++] = base64_map[ FOURTH_SIX_INDEX ];
}
/* If a remainder is available, we do a very similar process - but we also
ensure that the output string is padded to a multiple of 4 - using '=' */
if ((len-cursor) > 0) {
// Buffer final bytes, unused space should be nullified.
for (int j = 0; j < 3; j++) {
if (cursor < len) {
buf[j] = *(src + cursor++);
continue;
}
buf[j] = '\0';
}
// First remainder will always be valid, fallback to '=' (64 on map) on
// subsequent output values.
encoded[encoded_counter++] = base64_map[ FIRST_SIX_INDEX ];
encoded[encoded_counter++] = base64_map[ (SECOND_SIX_INDEX > 0) ? SECOND_SIX_INDEX : 64 ];
encoded[encoded_counter++] = base64_map[ (THIRD_SIX_INDEX > 0) ? THIRD_SIX_INDEX : 64 ];
encoded[encoded_counter++] = base64_map[ (FOURTH_SIX_INDEX > 0) ? FOURTH_SIX_INDEX : 64 ];
}
encoded[encoded_counter++] = '\0';
return encoded;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment