Thursday, July 21, 2011

Base64 Encoding and Decoding in C

 
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.



--
Sam

6 comments:

Anonymous said...

Im searching for this a looong way! worked great. Thanks :)

emmeeffe said...

Maybe a little bug on my VS2008.
Set input[0] = 0xFF, shifting right gives 0xFF anyway
I solved it this way

int encodeblock(char *input, char *output, int oplen){
...
encodedstr[0] = encodingtabe[ (input[0] & 0xfc) >> 2 ];
...

Anonymous said...

this will only let me encode one word at a time. how can i encode a string of text?

Unknown said...

it was grate post ... worked with copy pasting the code... Many thanks

Joel RF said...

Small changes to make it decode binary data and return the decoded length:

#define TABLELEN 64

int decodeblock(char *input, char *output, int index)
{
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;

memcpy(output + index, decodedstr, ENCODERBLOCKLEN);

return ENCODERBLOCKLEN;
}

int base64_decode(char *input, char *output, int oplen)
{
int length = 0;
char *charval = 0;
char decoderinput[ENCODERLEN + 1] = "";
int index = 0, asciival = 0, computeval = 0, iplen = 0;
char encodingtable[TABLELEN + 1] = BASE64CHARSET;

iplen = strlen(input);
while (index < iplen)
{
asciival = (int)input[index];
if (asciival == PADDINGCHAR)
{
length += decodeblock(decoderinput, output, length);
break;
}
else
{
charval = strchr(encodingtable, asciival);
if (charval)
{
decoderinput[computeval] = charval - encodingtable;
computeval = (computeval + 1) % 4;
if(computeval == 0)
{
length += decodeblock(decoderinput, output, length);
decoderinput[0] = decoderinput[1] = decoderinput[2] = decoderinput[3] = 0;
}
}
}
index++;
}

return length;
}

Unknown said...

Not work with cyrillic symbols (((
input:
Ivanov is an engineer ебаная ебань!

output:
Base64 Encoded value: SXZhbm92IGlzIGFuIGVuZ2luZWVyINC1�LHNC9�LDR�yDQ�dCx�LDQ�dGMIQ==
Base64 Decoded value: Ivanov is an engineer е,t

good base64:
SXZhbm92IGlzIGFuIGVuZ2luZWVyINC10LHQsNC90LDRjyDQtdCx0LDQvdGMIQ==

Post a Comment

Tamil News Live Online HD

Tamil News Live Online HD