Like C, C++ does not natively support Base64 decoding, so to implement it in C++ you must either use an external library or write your own implementation to execute the method.
In this article, we’ll introduce you to suitable external libraries and explain the Base64 algorithm in case you want to implement it yourself.
What is Base64?
Base64 is a method for encoding binary data into a human-readable format that may be easily shared between systems. Encoding includes transforming byte sequences into a set of ASCII characters to ensure interoperability with text-based platforms. Although it is not ideal for encryption, Base64 encoding is useful for situations such as incorporating images in emails or embedding files within code since it simplifies the handling of binary data in a variety of applications.
What is C++?
C++ is a robust and versatile programming language that is well-known for its speed and flexibility. It combines high-level and low-level programming features, making it appropriate for a wide range of applications ranging from system software to game creation. C++ supports object-oriented programming, memory management, and the ability to write efficient and optimized code.
Base64 Encoding and Decoding in C++
C++ does not have any native functions for Base64 encoding and decoding. Base64 encoding and decoding can, however, be accomplished using standard library functions for character manipulation and arithmetic operations. This necessitates the creation of custom code to divide the binary data into groups, translate those groups into ASCII characters, and manage padding.
Many developers prefer to use third-party libraries that provide ready-made functions for Base64 encoding and decoding to simplify the process and boost code efficiency. Here are some popular libraries to consider:
- Boost C++ Libraries: The Boost C++ Libraries include a
base64
module that provides functions for encoding and decoding data. Boost is widely used and well-documented, making it a reliable choice. - OpenSSL: While OpenSSL is primarily known for its cryptography features, it also includes functions for Base64 encoding and decoding. The library is widely used in security-sensitive applications and provides efficient solutions.
- Poco C++ Libraries: Poco is another set of C++ libraries that includes a Base64 class, making it easy to perform encoding and decoding operations.
When using third-party libraries, you typically follow these steps:
- Include the Library Headers: Include the appropriate header files from the library in your C++ source code using the
#include
directive. - Linking: If the library is provided as a compiled object file or shared library, you need to link your code with it during the compilation process. Refer to the library’s documentation for specific linking instructions.
- Use Library Functions: Once the library is included and linked, you can use its functions to perform Base64 encoding and decoding operations on your data.
Here is a more detailed description.
Example: Base64 Encoding with OpenSSL
Here’s a basic example in C++ that uses OpenSSL to encode binary data into Base64:
#include <openssl/bio.h> #include <openssl/evp.h> std::string Base64Encode(const std::string &input) { BIO *bio, *b64; BUF_MEM *bufferPtr; b64 = BIO_new(BIO_f_base64()); bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); BIO_write(bio, input.c_str(), input.length()); BIO_flush(bio); BIO_get_mem_ptr(bio, &bufferPtr); std::string encoded(bufferPtr->data, bufferPtr->length); BIO_free_all(bio); return encoded; } int main() { std::string data = "B64Encode.com"; std::string encoded = Base64Encode(data); std::cout << "Encoded: " << encoded << std::endl; return 0; }
In this example, the OpenSSL library is used to perform Base64 encoding on the input data. The Base64Encode
function takes binary input data and returns its Base64-encoded version.
Example: Base64 Decoding with OpenSSL
Here’s a basic example of Base64 decoding in C++ using OpenSSL:
#include <openssl/bio.h> #include <openssl/evp.h> std::string Base64Decode(const std::string &input) { BIO *bio, *b64; char *buffer = new char[input.size()]; b64 = BIO_new(BIO_f_base64()); bio = BIO_new_mem_buf(input.c_str(), -1); bio = BIO_push(b64, bio); BIO_read(bio, buffer, input.size()); BIO_free_all(bio); std::string decoded(buffer); delete[] buffer; return decoded; } int main() { std::string encodedData = "QjY0RW5jb2RlLmNvbQ=="; std::string decoded = Base64Decode(encodedData); std::cout << "Decoded: " << decoded << std::endl; return 0; }
In this example, the Base64Decode
function decodes a Base64-encoded string into its original binary form using OpenSSL. The function receives the specified encoded string and returns the decoded binary data.
Implementing Base64 Encoding Algorithm in Pseudocode
If you don’t want to use an external library, you can try to implement Base64 encoding and decoding yourself. The good news is that Base64 is not a very complicated method, so it is not too difficult to program.
Since Base64 encoding operates on a language-independent concept, any programming language can use it. The following illustration shows how to use a language-independent technique to implement Base64 encoding.
If you want more details, this article explains Base64 in more detail.
Here’s an example of a language-agnostic algorithm in pseudocode:
function base64_encode(input) // The base character set const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" // The length of the input let input_length = length(input) // The output let output = "" // Process the input in 3-byte blocks for i from 0 to input_length - 1 step 3 // The value of the block let block_value = (input[i] << 16) + (input[i + 1] << 8) + input[i + 2] // Encode the block into 4 characters for j from 0 to 3 let index = (block_value >> ((3 - j) * 6)) & 0x3F output += BASE64_CHARS[index] end for end for // Pad the output length with '=' characters if necessary let padding = input_length % 3 if padding > 0 for i from 0 to (3 - padding) output[output.length - i - 1] = '=' end for end if return output end function
Here is an explanation of the code, broken down into a list:
- The binary data to be encoded is passed as an input parameter to the base64_encode function.
- The basic character set for the encoding, which consists of 64 characters, is designated by the constant BASE64_CHARS.
- The length of the input data is used to calculate the input_length variable.
- The output variable, which will hold the result of the encoding, is initially set to an empty string.
- A for loop that iterates from 0 to input_length – 1 with a step of 3 processes the input data in 3-byte blocks.
- The first byte is shifted left by 16 bits for each block, the second byte is shifted left by 8 bits, and the third byte is added to determine the block_value variable for each block.
- A second for loop that iterates from 0 to 3 is then used to encode the block into 4 characters.
- For each character, an
index
is calculated by shifting theblock_value
to the right by a multiple of 6 bits and masking it with 0x3F. - The character at this index in the
BASE64_CHARS
constant is then appended to theoutput
string. - After all blocks have been processed, the output length is padded with ‘=’ characters if necessary.
- To accomplish this, the padding is determined by dividing the input_length by 3.
- A for loop iterates from 0 to (3 – padding) and replaces the final characters of the output string with ‘=‘ characters if padding is higher than 0.
- The function then returns the result that was encoded and saved in the output variable.
Implementing Base64 Decoding Algorithm in Pseudocode
Now let’s look at decoding independently of the programming language.
function base64_decode(input) // The base character set const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" // The length of the input let input_length = length(input) // The output let output = [] // Process the input in 4-character blocks for i from 0 to input_length - 1 step 4 // The value of the block let block_value = (index_of(BASE64_CHARS, input[i]) << 18) + (index_of(BASE64_CHARS, input[i + 1]) << 12) + (index_of(BASE64_CHARS, input[i + 2]) << 6) + index_of(BASE64_CHARS, input[i + 3]) // Decode the block into 3 bytes for j from 0 to 2 let byte = (block_value >> ((2 - j) * 8)) & 0xFF output.append(byte) end for end for // Remove any padding bytes from the output let padding = count(input, '=') if padding > 0 output = output[0:output.length - padding] end if return output end function
- The
base64_decode
function takes aninput
parameter, which is the string of characters to be decoded. - The
BASE64_CHARS
constant is defined as the base character set for the decoding, which consists of 64 characters. - The length of the input string is used to calculate the input_length variable.
- The output variable, which will hold the result of the decoding, is initialized as an empty array.
- The input data is processed in 4-character blocks using a
for
loop that iterates from 0 toinput_length - 1
with a step of 4. - For each block, the
block_value
variable is calculated by shifting the index of each character in theBASE64_CHARS
constant to the left by a multiple of 6 bits and adding them together. - Then, a second for loop iterating from 0 to 2 decodes the block into 3 bytes.
- By moving the block_value to the right by a multiple of 8 bits and masking it with 0xFF, a value is computed for each byte. This value is then appended to the output array.
- If necessary, any padding bytes are taken out of the output once all blocks have been processed. The count function is used to determine how many padding characters (‘=‘) are present in the input, and then the appropriate number of bytes are subtracted from the end of the output array.
- Finally, the function returns the decoded result stored in the
output
array.