Home > Uncategorized > Base64 encoding

Base64 encoding

Base64 encoding is a way to convert, or encode, binary data using text characters only. I stumbled upon a question on stackoverflow concering how to use the boost library for such a task. Indeed, it turns out to be possible but the template type definition turns out to be, well, not for the faint hearted.

 typedef 
     insert_linebreaks<         // insert line breaks every 72 characters
         base64_from_binary<    // convert binary values of base64 characters
             transform_width<   // retrieve 6 bit integers from a sequence of 8 bit bytes
                 const char *,
                 6,
                 8
             >
         >
         ,72
     >
     base64_text; // compose all the above operations in to a new iterator

 

Wow. No matter how impressive this is, it is also hard to read and use, unfortunately. Just for curiosity, I wondered how much code that a plain, no tricks at all, implementation would require. So… I wrote one:

#include "stdafx.h"

#include <string.h>

 

unsigned char* base64_encode(const unsigned char* in, size_t length)

{

    const char * lookup_table =

        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

        "abcdefghijklmnopqrstuvwxyz"

        "0123456789"

        "+/";

 

    const size_t rlength = length%3==0 ? length/3*4+1 : length/3*4+5;

    unsigned char* out = new unsigned char[rlength];

    size_t i=0, j=0;

    for(; i<length-2; i+=3, j+=4)

    {

        out[j] = lookup_table[in[i] >> 2];

        out[j+1] = lookup_table[((in[i] & 0x03) << 4) + (in[i+1] >> 4)];

        out[j+2] = lookup_table[((in[i+1] & 0x0F) << 2) + (in[i+2] >> 6)];

        out[j+3] = lookup_table[in[i+2] & 0x3F];

    }

 

    if (i < length)

    {

        out[j] = lookup_table[in[i] >> 2];

        out[j+1] = lookup_table[((in[i] & 0x03) << 4) + (i+1 < length ? (in[i+1] >> 4) : 0)];

        out[j+2] = i+1 < length ? lookup_table[(in[i+1] & 0x0F) << 2] : ‘=’;   

        out[j+3] = ‘=’;

        j+=4;

    }

 

    out[j] = 0;

    return out;

}

 

char* base64_encode_str(const char* in, size_t length)

{

    return reinterpret_cast<char*>(base64_encode( reinterpret_cast<const unsigned char*>(in), length));

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    const char* in = "this is sample data that could have been binary as well";

    char* out = base64_encode_str(in, ::strlen(in));

    printf("%s -> %s\n", in, out);

    delete[] out;

}

 

To be fair, this one does not handle line breaks which the boost version did. On the other hand it handles data sizes that are not multiples of three. So, this was my version. If you need a library you might want to have a look at this one instead. A gpu version (which is incredibly cool of course) exists on codeplex. In .NET it is more convenient to turn to Convert.ToBase64.

Advertisements
Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: