Base64 is a method of encoding arbitrary data as plain ASCII text. It is one of the techniques employed by the MIME standard to send data other than plain text. Base64 encoding takes three bytes, each consisting of eight bits, and represents them as four printable characters in the ASCII standard. It does that in essentially two steps.
The first step is to convert three bytes to four numbers of six bits. Base64 only uses 6 bits. The 64 characters are 10 digits (0 to 9), 26 lowercase characters (a to z), 26 uppercase characters (A to Z) as well as ‘+’ and ‘/’.
For example, the three bytes are 155, 162 and 233, the corresponding bit stream is 100110111010001011101001, which in turn corresponds to the 6-bit values 38, 58, 11 and 41.
These numbers are converted to ASCII characters in the second step using the Base64 encoding table. The 6-bit values of our example translate to the ASCII sequence “m6Lp”.
155 -> 10011011 162 -> 10100010 233 -> 11101001 100110 -> 38 111010 -> 58 001011 -> 11 101001 -> 41 38 -> m 58 -> 6 11 -> L 41 -> p
This two-step process is applied to the whole sequence of bytes that are encoded. If the size of the original data in bytes is a multiple of three, everything works fine. If it is not, we might end up with one or two 8-bit bytes. For proper encoding, we have to append enough bytes with a value of ‘0’ to create a 3-byte group. The Base64 uses ‘=’ as a padding character.
Sample C Program
The following program in C can be used for Base64 Encoding and Decoding.
/* ================================================== Name : Base64EncodeDecode.c Author : Version : Copyright : Description : Base64EncoderDecoder in C, Ansi-style ================================================== */ #include <stdio.h> #include <string.h> #include <stdlib.h> /* Macro definitions */ #define TABLELEN 63 #define BUFFFERLEN 128 #define ENCODERLEN 4 #define ENCODEROPLEN 0 #define ENCODERBLOCKLEN 3 #define PADDINGCHAR '=' #define BASE64CHARSET "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/"; /* Function prototypes */ int Base64Encode(char *input, char *output, int oplen); int encodeblock(char *input, char *output, int oplen); int Base64Decode(char *input, char *output, int oplen); int decodeblock(char *input, char *output, int oplen); /* Its always better to move the macros and function prototypes to a header file */ int decodeblock(char *input, char *output, int oplen){ int rc = 0; char decodedstr[ENCODERLEN + 1] = ""; decodedstr[0] = input[0] << 2 | input[1] >> 4; decodedstr[1] = input[1] << 4 | input[2] >> 2; decodedstr[2] = input[2] << 6 | input[3] >> 0; strncat(output, decodedstr, oplen-strlen(output)); return rc; } int Base64Decode(char *input, char *output, int oplen){ char *charval = 0; char decoderinput[ENCODERLEN + 1] = ""; char encodingtabe[TABLELEN + 1] = BASE64CHARSET; int index = 0, asciival = 0, computeval = 0, iplen = 0, rc = 0; iplen = strlen(input); while(index < iplen){ asciival = (int)input[index]; if(asciival == PADDINGCHAR){ rc = decodeblock(decoderinput, output, oplen); break; }else{ charval = strchr(encodingtabe, asciival); if(charval){ decoderinput[computeval] = charval - encodingtabe; computeval = (computeval + 1) % 4; if(computeval == 0){ rc = decodeblock(decoderinput, output, oplen); decoderinput[0] = decoderinput[1] = decoderinput[2] = decoderinput[3] = 0; } } } index++; } return rc; } int encodeblock(char *input, char *output, int oplen){ int rc = 0, iplen = 0; char encodedstr[ENCODERLEN + 1] = ""; char encodingtabe[TABLELEN + 1] = BASE64CHARSET; iplen = strlen(input); encodedstr[0] = encodingtabe[ input[0] >> 2 ]; encodedstr[1] = encodingtabe[ ((input[0] & 0x03) << 4) | ((input[1] & 0xf0) >> 4) ]; encodedstr[2] = (iplen > 1 ? encodingtabe[ ((input[1] & 0x0f) << 2) | ((input[2] & 0xc0) >> 6) ] : PADDINGCHAR); encodedstr[3] = (iplen > 2 ? encodingtabe[ input[2] & 0x3f ] : PADDINGCHAR); strncat(output, encodedstr, oplen-strlen(output)); return rc; } int Base64Encode(char *input, char *output, int oplen){ int rc = 0; int index = 0, ipindex = 0, iplen = 0; char encoderinput[ENCODERBLOCKLEN + 1] = ""; iplen = strlen(input); while(ipindex < iplen){ for(index = 0; index < 3; index++){ if(ipindex < iplen){ encoderinput[index] = input[ipindex]; }else{ encoderinput[index] = 0; } ipindex++; } rc = encodeblock(encoderinput, output, oplen); } return rc; } int main(void) { int rc = 0; char input[BUFFFERLEN + 1] = ""; char encodedoutput[BUFFFERLEN + 1] = ""; char decodedoutput[BUFFFERLEN + 1] = ""; printf("Enter a string: n"); scanf("%s", input); rc = Base64Encode(input, encodedoutput, BUFFFERLEN); printf("Base64 Encoded value: %sn", encodedoutput); rc = Base64Decode(encodedoutput, decodedoutput, BUFFFERLEN); printf("Base64 Decoded value: %s", decodedoutput); return rc; }
You can refer to source article for more details.