como-usar-base64-esp32

Qué es y cómo usar Base64 en ESP32

Base64 es un esquema de codificación que permite representar datos binarios en un formato de texto ASCII.

Esto es útil cuando necesitamos transmitir datos binarios a través de protocolos que solo admiten texto (por ejemplo, correos electrónicos o URLs).

Características de Base64

  • Representación de datos binarios: Base64 convierte datos binarios en texto, lo que facilita su transmisión y almacenamiento.
  • Tamaño aumentado: Los datos codificados en Base64 ocupan aproximadamente un 33% más de espacio que los datos originales.
  • Uso común: Se utiliza en aplicaciones como correos electrónicos (adjuntos), URLs, autenticación HTTP y almacenamiento de datos.

El sistema Base64 también está relacionado con aplicaciones de seguridad. Muchas veces interviene como una parte del proceso de encriptación o autentificación.

Sin embargo, pero en si mismo no es un método de encriptación. Los datos codificados en Base64 pueden ser fácilmente decodificados.

Si necesitas proteger la confidencialidad de los datos, debes utilizar métodos de encriptación como AES o RSA.

¿Cómo funciona Base64?

La codificación Base64 utiliza un conjunto de 64 caracteres (de ahí su nombre), elegidos por ser son comunes en la mayoría de los sistemas.

Estos caracteres son letras mayúsculas (A-Z), letras minúsculas (a-z), números (0-9) y dos caracteres especiales, generalmente ”+” y ”/“.

Cada uno de estos caracteres puede codificar 6bits de información (2^6 = 64). Pero nuestra información original estaba codificada en múltiplos de 8bits.

Para realizar la conversión,

  • Dividimos los datos binarios en bloques de 3 bytes (3 x 8 = 24 bits)
  • Convertimos los bloques en 4 caracteres ASCII (4 x 6 = 24 bits).

Pero no siempre la información que queramos codificar va a ser un múltiplo de 3 bytes. Al final de la secuencia, nos pueden sobrar 1 o 2 bytes.

esp32-base64

Padding en función de los bytes que sobran

Así que se utiliza el carácter ”=” como relleno.

  • Si sobra 1 byte, se añaden 2 caracteres =.
  • Si sobran 2 bytes, se añade 1 carácter =.
  • Si la cantidad de bytes es un múltiplo de 3, no es necesario padding.

Ejemplo de codificación Base64

Vamos a verlo con un ejemplo. Imaginemos que tenemos estos datos binarios que queremos enviar.

01001000 01101111 01101100 01100001

Para pasarlos a Base64 divide estos bytes en bloques de 6 bits:

010010 000110 111101 101100 011000 01

El bloque final lo completo con 0

010010 000110 111101 101100 011000 0100000

Cada bloque de 6 bits se convierte en un carácter Base64:

S G 9 s Y Q

Como solo tengo 6 letras, y necesito un múltiplo de 4, añado dos =.

SG9sYQ==

Implementación de Base64 en ESP32

El ESP32 cuenta con una biblioteca (base64.h) que nos permite codificar y decodificar datos en Base64.

Vamos a ver cómo utilizar la librería en un proyecto de ESP32.

#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);
}

Y si lo ejecutamos veréis algo como esto

base64

Ejemplos prácticos