Well, I was looking for a Base64 library recently, and I thought, “I know, I bet it is in Boost, I have Boost, and Boost has everything.” And it turns out that it does! Kind of. But it’s a bit odd and sadly incomplete.
So let’s fix it.
To start with, I didn’t really have a clue how to plug these Boost components together, so a quick scout on the beloved StackOverflow (a Programmer’s Guide to the Galaxy) yields the following code, which I have slightly modified:
using namespace boost::archive::iterators;
typedef
insert_linebreaks<
base64_from_binary<
transform_width<
const unsigned char *
,6
,8
>
>
,76
>
base64Iterator;
Disgusting, isn’t it? It also doesn’t work. It will only work when the data you use is a multiple of three, so we’ll have to pad it ourselves. Here’s the full code for that:
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/transform_width.hpp>
namespace Base64Utilities
{
std::string ToBase64(std::vector<unsigned char> data)
{
using namespace boost::archive::iterators;
unsigned int paddedCharacters = 0;
while(data.size() % 3 != 0)
{
paddedCharacters++;
data.push_back(0x00);
}
typedef
insert_linebreaks<
base64_from_binary<
transform_width<
const unsigned char *
,6
,8
>
>
,76
>
base64Iterator;
std::string encodedString(
base64Iterator(&data[0]),
base64Iterator(&data[0] + (data.size() - paddedCharacters)));
for(unsigned int i = 0; i < paddedCharacters; i++)
{
encodedString.push_back('=');
}
return encodedString;
}
}
It’s not that elegant but it seems to work. Can you improve on this code? Can you write the decode function? Check your answers with this excellent Online Base64 Converter.
Leave your comments below!