Base64 Encoder in C++

Arne Olav Hallingstad
16th January 2011
Home

Introduction

This is an implementation of a Base64 encoder in C++. I made the class as I was working on the 3n + 1 programming challenge.

Using Base64 encoding one can encode (or transform) any type of data as a string. This is useful for embedding data objects in text files, like embedding pictures in web pages, or sending some data as part of a URI over the internet.

Encoding in Base64 is not a type of encryption though as the original data can easily be found by anyone that recognizes it being Base64 encoded (the padding characters "=" at the end of the string is the easiest give away).

An example from Wikipedia that embeds an image in a web page using the Data URI Scheme:

	<img src="data:image/png;base64,
	iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
	C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
	AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
	REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
	ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
	vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />

The image:

Red dot

Code

The implementation of the Base64 Encoder is based on the RFC 4648 standard from October 2006:

/*
=============================================================

aoBase64Encoder

Author: Arne Olav Hallingstad
History:
Initial implementation 2011-01-16

Encodes a data stream in Base64 which can be passed along
in strings, used in particular as part of the URI in
HTTP-requests

The Base64 encoded string needs 4 bytes per 3 bytes in the
original data stream + up to 3 bytes in padding at the
end (encoded string must be multiple of 4). Thus encoded size
is roughly 33,3% of the original size.

Based on RFC 4648 (http://tools.ietf.org/html/rfc4648)

=============================================================
*/

class aoBase64Encoder {
public:
	static const char BASE64_PAD_CHAR = '=';

						aoBase64Encoder();
						~aoBase64Encoder();

						// Sets the encoded data for object
						// Frees the previously encoded data if any
	void			Reset( const char* encodedData, unsigned int encodedDataSize );
	void			Reset();
						// Encodes the input and stores it in the object.
						// Frees the previously encoded data if any
	void			Encode( const unsigned char* data, unsigned int dataSize );
						// Decodes and returns the currently encoded data
						// Decoded data is freed when object is destroyed
	bool			Decode( unsigned char*& data, unsigned int& dataSize );
						// Get pointer to the encoded data
	const char*		GetEncoded() const { return encoded; }
						// Get size of encoded data
	unsigned int	GetEncodedSize() const { return encodedSize; }
						// Get pointer to the decoded data
						// decodes encoded data if necessary
	const unsigned char* GetDecoded();
						// Get size of encoded data
						// decodes encoded data if necessary
	unsigned int	GetDecodedSize();

private:
	unsigned int	GetBase64Size( unsigned int dataSize ) { return ( ( dataSize + 2 ) / 3 ) * 4; }
						// this is the padded data size, we
						// cannot know the original data size unless we also look at the pad characters
	unsigned int	GetDataSize( unsigned int base64Size );

	char*			encoded;
	unsigned int	encodedSize;
	unsigned char*	decoded;
	unsigned int	decodedSize;
};

Example

To use the encoder use the Encode and Decode member functions:

	// encode data, consisting of numBytes bytes.
	aoBase64Encoder encoder;
	encoder.Encode( data, numBytes );

	// decode the encoded data into decoded and decodedSize.
	// note that decoded is only a valid pointer while
	// encoder object is in scope!
	unsigned char* decoded;
	unsigned int decodedSize;
	if ( encoder.Decode( decoded, decodedSize ) ) {
		// do stuff with decoded data
	}

Download

Base64EncoderSrc.zip (VS2010 project)
Base64Encoder.cpp
Base64Encoder.h

References


Tweet

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.