Base64 Encode & Decode in C++
Encode or decode below — it runs locally in your browser — then grab the canonical C++ code. The C++ standard library has no Base64, so you drop in a small self-contained std::string encoder, or call OpenSSL's EVP functions if you already link it.
Encode and decode a string
Encoding takes three bytes (24 bits) at a time, splits them into four 6-bit groups, and indexes each into the alphabet — padding the tail with =. Decoding reverses it with a reusable lookup table:
#include <array>
#include <cstdint>
#include <string>
static const char kTable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string base64_encode(const unsigned char* data, std::size_t len) {
std::string out;
out.reserve(((len + 2) / 3) * 4);
std::size_t i = 0;
while (i + 3 <= len) {
std::uint32_t n = (data[i] << 16) | (data[i + 1] << 8) | data[i + 2];
out.push_back(kTable[(n >> 18) & 0x3F]);
out.push_back(kTable[(n >> 12) & 0x3F]);
out.push_back(kTable[(n >> 6) & 0x3F]);
out.push_back(kTable[n & 0x3F]);
i += 3;
}
if (std::size_t rem = len - i; rem > 0) {
std::uint32_t n = data[i] << 16;
if (rem == 2) n |= data[i + 1] << 8;
out.push_back(kTable[(n >> 18) & 0x3F]);
out.push_back(kTable[(n >> 12) & 0x3F]);
out.push_back(rem == 2 ? kTable[(n >> 6) & 0x3F] : '=');
out.push_back('=');
}
return out;
}
std::string base64_decode(const std::string& in) {
static const auto table = [] {
std::array<int, 256> t; t.fill(-1);
for (int i = 0; i < 64; ++i)
t[static_cast<unsigned char>(kTable[i])] = i;
return t;
}();
std::string out;
std::uint32_t buf = 0; int bits = 0;
for (unsigned char c : in) {
if (c == '=') break;
int v = table[c];
if (v < 0) continue; // skip whitespace / newlines
buf = (buf << 6) | v; bits += 6;
if (bits >= 8) {
bits -= 8;
out.push_back(static_cast<char>((buf >> bits) & 0xFF));
}
}
return out;
}
Tip: the C++ standard library has no Base64 — you either roll your own (as above) or use a library such as OpenSSL or Boost.Beast. Always index the decode table with unsigned char: a signed char > 127 is undefined behavior.
Using OpenSSL (EVP)
If your app already links OpenSSL, EVP_EncodeBlock / EVP_DecodeBlock from <openssl/evp.h> do it in one call. Link with -lcrypto:
#include <openssl/evp.h>
#include <string>
#include <vector>
std::string openssl_encode(const std::string& input) {
std::string out;
out.resize(4 * ((input.size() + 2) / 3)); // exact encoded size
int n = EVP_EncodeBlock(
reinterpret_cast<unsigned char*>(out.data()),
reinterpret_cast<const unsigned char*>(input.data()),
static_cast<int>(input.size()));
out.resize(n);
return out;
}
std::string openssl_decode(const std::string& encoded) {
std::vector<unsigned char> out(3 * (encoded.size() / 4));
int n = EVP_DecodeBlock(
out.data(),
reinterpret_cast<const unsigned char*>(encoded.data()),
static_cast<int>(encoded.size()));
if (n < 0) return {}; // decode error
return std::string(reinterpret_cast<char*>(out.data()), n);
}
EVP_DecodeBlock always returns a multiple of three and does not account for padding — count the trailing = characters (0, 1, or 2) and subtract that many bytes for the true length, or use the streaming EVP_DecodeUpdate / EVP_DecodeFinal API.
URL-safe variant
The URL-safe alphabet (RFC 4648 §5) swaps + for - and / for _, and usually drops the = padding. With the custom encoder above it is a two-character change to the alphabet table:
static const char kUrlSafeTable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789-_"; // '+' -> '-', '/' -> '_'
std::string base64url_encode(const unsigned char* data, std::size_t len) {
std::string out = base64_encode(data, len); // standard encode
for (char& c : out) {
if (c == '+') c = '-';
else if (c == '/') c = '_';
}
while (!out.empty() && out.back() == '=') out.pop_back(); // strip padding
return out;
}
To decode, translate - and _ back to + and / first. The bit-count decoder above reconstructs bytes without relying on padding, so unpadded input works as-is.
Frequently asked questions
Does C++ have a built-in Base64 function?
No. As of C++23 there is no Base64 in the standard library — no std::base64_encode, no header. You roll your own (under 100 lines) or use OpenSSL or Boost.Beast.
How do I Base64 encode a string in C++?
Use a small std::string encoder: base64_encode((const unsigned char*)"Hello", 5) returns "SGVsbG8=".
How do I Base64 encode with OpenSSL in C++?
Call EVP_EncodeBlock / EVP_DecodeBlock from <openssl/evp.h> and link with -lcrypto; remember EVP_DecodeBlock ignores padding.
How do I do URL-safe Base64 in C++?
Swap +// for -/_ in the alphabet table and strip the = padding (RFC 4648 §5).
Need image, file, or URL-safe modes?
The main base64.dev tool handles text, images, files, and URL-safe Base64 with auto-detect.
Open base64.dev →