Language: EN

como-usar-base64-esp32

What is Base64 and how to use it in ESP32

Base64 is an encoding scheme that allows representing binary data in an ASCII text format.

This is useful when we need to transmit binary data through protocols that only support text (for example, emails or URLs).

Features of Base64

  • Binary data representation: Base64 converts binary data into text, making it easier to transmit and store.
  • Increased size: Base64 encoded data takes up approximately 33% more space than the original data.
  • Common usage: It is used in applications such as emails (attachments), URLs, HTTP authentication, and data storage.

The Base64 system is also related to security applications. Many times it plays a part in the encryption or authentication process.

However, it is itself not an encryption method. Data encoded in Base64 can be easily decoded.

If you need to protect the confidentiality of the data, you should use encryption methods like AES or RSA.

How does Base64 work?

Base64 encoding uses a set of 64 characters (hence its name), chosen for being common in most systems.

These characters are uppercase letters (A-Z), lowercase letters (a-z), numbers (0-9), and two special characters, generally ”+” and ”/“.

Each of these characters can encode 6 bits of information (2^6 = 64). But our original information was encoded in multiples of 8 bits.

To perform the conversion,

  • We divide the binary data into blocks of 3 bytes (3 x 8 = 24 bits)
  • We convert the blocks into 4 ASCII characters (4 x 6 = 24 bits).

But the information we want to encode will not always be a multiple of 3 bytes. At the end of the sequence, we may have 1 or 2 leftover bytes.

esp32-base64

Padding based on leftover bytes

So the character ”=” is used as padding.

  • If 1 byte is leftover, 2 ”=” characters are added.
  • If 2 bytes are leftover, 1 ”=” character is added.
  • If the number of bytes is a multiple of 3, padding is not necessary.

Example of Base64 encoding

Let’s see it with an example. Imagine we have this binary data that we want to send.

01001000 01101111 01101100 01100001

To convert it to Base64, divide these bytes into blocks of 6 bits:

010010 000110 111101 101100 011000 01

I complete the final block with 0

010010 000110 111101 101100 011000 0100000

Each 6-bit block is converted into a Base64 character:

S G 9 s Y Q

Since I only have 6 letters, and I need a multiple of 4, I add two =.

SG9sYQ==

Base64 Implementation in ESP32

The ESP32 has a library (base64.h) that allows us to encode and decode data in Base64.

Let’s see how to use the library in an ESP32 project.

#include "stdlib.h"
#include "mbedtls/base64.h"

void printBlockAsUtf8(std::vector<uint8_t> data)
{
	for(int i = 0; i < data.size(); i++)
	{
		Serial.print((char)data[i]);
	}
}

std::string encode_base64(std::vector<uint8_t>& data)
{
	size_t outputLength;
	mbedtls_base64_encode(nullptr, 0, &outputLength, (unsigned char*)data.data(), data.size());

	std::vector<uint8_t> encoded(outputLength);
	mbedtls_base64_encode(encoded.data(), outputLength, &outputLength, (unsigned char*)data.data(), data.size());

	std::string rst((char*)encoded.data(), outputLength);
	return rst;
}

std::vector<uint8_t> decode_base64(std::string& text)
{
	size_t outputLength;
	mbedtls_base64_decode(nullptr, 0, &outputLength, (unsigned char*)text.c_str(), text.length());

	std::vector<uint8_t> decoded(outputLength);
	mbedtls_base64_decode(decoded.data(), outputLength, &outputLength, (unsigned char*)text.c_str(), text.length());
	return decoded;
}

void setup()
{
	Serial.begin(115200);
	delay(2000);

	std::string message = "www.luisllamas.es";

	std::vector<uint8_t> data(message.begin(), message.end());
	auto encoded = encode_base64(data);
	auto decoded = decode_base64(encoded);

	Serial.printf("Original (%d bytes): ", data.size());
	printBlockAsUtf8(data);
	Serial.println();

	Serial.printf("Encoded (%d bytes): ", encoded.length());
	Serial.print(encoded.c_str());
	Serial.println();

	Serial.printf("Decoded (%d bytes): ", decoded.size());
	printBlockAsUtf8(decoded);
}

void loop()
{
	delay(1000);
}

And if we run it, you will see something like this

base64

Practical Examples