🔢 Qué es Base64 y por qué es el traductor universal de la web
¡Antes de nada, feliz año! Llevaba mucho tiempo sin dar la matraca por aquí, una vez acabados los patrones de diseño más o menos, vamos a hacer post de forma muy random, hoy le dedicamos unos minutos a Base64.
Si llevas un tiempo programando seguro que te has encontrado alguna vez con una cadena de texto muy larga, ilegible y que suele acabar con uno o dos signos de igual (=). Rollo esto:
SG9sYSBNdW5kbyE=
Eso es Base64. No es encriptación (ojito con esto), es codificación. Es la herramienta que nos permite “disfrazar” datos complejos (imágenes, PDFs, audios) para que parezcan texto simple y puedan viajar sin romperse por internet.

🤯 1. El problema que resuelve
Situación inicial: Internet solo hablaba texto
Imagina los inicios de Internet y los emails y vaina. Los protocolos antiguos estaban diseñados para transportar texto (ASCII) de 7 bits. Solo 128 caracteres posibles: letras del inglés, números y unos pocos de símbolos.
Si intentabas enviar una imagen (que es un archivo binario, lleno de ceros y unos que no corresponden a letras legibles) a través de un sistema diseñado para texto, ocurría el desastre:
- El sistema intentaba interpretar un byte de la imagen como una letra.
- Se encontraba con un “carácter de control” (como un salto de línea o un byte nulo) donde no debía.
- El sistema pensaba que el mensaje había terminado o se corrompía la transmisión.
Se necesitaba una forma de meter una imagen dentro de un mensaje de texto sin que los servidores de correo o los navegadores se volvieran locos.
La solución en 60 segundos
Base64 pilla cualquier dato binario (una foto, un zip, un audio, etc.) y lo traduce a un alfabeto seguro de 64 caracteres que todos los sistemas entienden:
- Letras mayúsculas
A-Z(26 caracteres) - Letras minúsculas
a-z(26 caracteres) - Números
0-9(10 caracteres) - Dos símbolos extra:
+y/(2 caracteres)
26 + 26 + 10 + 2 = 64. De ahí el nombre. Tu imagen binaria se convierte en una cadena de letras y números que viaja segura por cualquier protocolo de texto.
¿Qué es Base64?
🌎 2. El Telégrafo y los Emojis
Imagina que quieres enviar un Emoji (😎) por un telégrafo antiguo que solo tiene botones para letras y números.
- El Dato Binario (El Emoji): Es información compleja que el medio de transporte (el telégrafo) no soporta nativamente.
- El Codificador (Base64): Tú decides que el código para 😎 será la palabra “GAFAS”.
- La Transmisión: Por el cable del telégrafo viaja la palabra
G-A-F-A-S. El telégrafo está feliz porque solo son letras. - El Receptor (Decodificador): Al otro lado, tu amigo recibe “GAFAS”, consulta su tabla de códigos, y sabe que debe dibujar un 😎.
Base64 hace exactamente esto, traduce bytes raros a letras seguras para el viaje y las vuelve a convertir al llegar.
| Concepto | En Binario (Peligroso) | En Base64 (Seguro) |
|---|---|---|
| Soporte | Cualquier valor (0-255). Incluye caracteres invisibles que rompen sistemas. | Solo caracteres imprimibles (A-Z, a-z, 0-9, +, /). |
| Tamaño | 100% (Tamaño original). | ~133% (Aumenta un 33% el tamaño). |
| Seguridad | Los datos están tal cual, sin transformar. | Ninguna. Cualquiera puede decodificarlo. No es encriptación. |
Si tengo una imagen de 3MB y la convierto a Base64, ¿cuánto ocupará aproximadamente?
📜 3. Un poco de Historia
El origen de Base64 está ligado al estándar MIME (Multipurpose Internet Mail Extensions), definido en 1996 en el RFC 2045. Cuando el correo electrónico empezó a popularizarse, se dieron cuenta de que enviar solo texto era muy aburrido. Querían enviar adjuntos como fotos y documentos.
Para conseguirlo sin cambiar toda la infraestructura de internet, inventaron Base64 para incrustar esos adjuntos dentro del cuerpo del mensaje. El protocolo SMTP seguía transportando texto plano, pero ese texto contenía la imagen codificada. MAGIC! 🧙♂️.
Cuando recibes un email con un adjunto, por debajo lo que viaja es algo así:
Content-Type: image/png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAA
HElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4O
HwAAAABJRU5ErkJggg==
Todo texto plano. El cliente de correo lee Content-Transfer-Encoding: base64, decodifica ese chorizo de letras y te muestra la imagen. Y tu mientras sin sospecharlo!.
🔢 4. La matemática paso a paso
La regla de oro es: 3 bytes se convierten en 4 caracteres.
Vamos a codificar la palabra “Hola” a mano para que veas cómo funciona por dentro.
Paso 1: Texto a bytes (ASCII)
| Carácter | Valor ASCII | Binario (8 bits) |
|---|---|---|
| H | 72 | 01001000 |
| o | 111 | 01101111 |
| l | 108 | 01101100 |
| a | 97 | 01100001 |
Paso 2: Juntar los bits y reagrupar de 6 en 6
Los primeros 3 caracteres (Hol) son 24 bits:
01001000 01101111 01101100
Los dividimos en 4 grupos de 6 bits:
010010 | 000110 | 111101 | 101100
Paso 3: Buscar cada grupo en la tabla Base64
| Grupo de 6 bits | Valor decimal | Carácter Base64 |
|---|---|---|
010010 | 18 | S |
000110 | 6 | G |
111101 | 61 | 9 |
101100 | 44 | s |
Primer bloque: SG9s
Paso 4: El último carácter y el padding
Nos queda a (solo 1 byte = 8 bits). Base64 necesita grupos de 3 bytes, así que rellena con ceros hasta tener 24 bits:
01100001 00000000 00000000
Reagrupamos:
011000 | 010000 | 000000 | 000000
| Grupo | Valor | Carácter |
|---|---|---|
011000 | 24 | Y |
010000 | 16 | Q |
| padding | — | = |
| padding | — | = |
Los dos últimos grupos eran relleno, así que se marcan con =.
Resultado final: SG9sYQ==
Eso es exactamente lo que te devuelve cualquier codificador Base64. No magic, just math.
¿Cuál es la regla de conversión fundamental de Base64?
¿Qué representa el signo igual (=) al final de una cadena Base64?
💻 5. Ejemplos en código
JavaScript
// Codificar
const codificado = btoa('Hola');
console.log(codificado); // "SG9sYQ=="
// Decodificar
const original = atob('SG9sYQ==');
console.log(original); // "Hola"
// Para texto con caracteres especiales (UTF-8):
const textoUTF8 = 'Año 2026 🎉';
const codificadoUTF8 = btoa(unescape(encodeURIComponent(textoUTF8)));
console.log(codificadoUTF8);
// Decodificar UTF-8:
const originalUTF8 = decodeURIComponent(escape(atob(codificadoUTF8)));
console.log(originalUTF8); // "Año 2026 🎉"
JavaScript (Node.js)
// Codificar
const codificado = Buffer.from('Hola').toString('base64');
console.log(codificado); // "SG9sYQ=="
// Decodificar
const original = Buffer.from('SG9sYQ==', 'base64').toString('utf-8');
console.log(original); // "Hola"
// Codificar un archivo entero
const fs = require('fs');
const imagen = fs.readFileSync('foto.png');
const imagenBase64 = imagen.toString('base64');
// Ahora puedes meter imagenBase64 en un JSON, un email, etc.
PHP
<?php
// Codificar
$codificado = base64_encode("Hola");
echo $codificado; // "SG9sYQ=="
// Decodificar
$original = base64_decode("SG9sYQ==");
echo $original; // "Hola"
// Codificar un archivo
$imagen = file_get_contents('foto.png');
$imagenBase64 = base64_encode($imagen);
// Generar un Data URI para HTML
$dataUri = "data:image/png;base64," . $imagenBase64;
echo "<img src=\"{$dataUri}\" />";
Python
import base64
# Codificar
codificado = base64.b64encode(b"Hola").decode('ascii')
print(codificado) # "SG9sYQ=="
# Decodificar
original = base64.b64decode("SG9sYQ==").decode('utf-8')
print(original) # "Hola"
# Codificar un archivo
with open('foto.png', 'rb') as f:
imagen_base64 = base64.b64encode(f.read()).decode('ascii')
Fíjate que todos los lenguajes lo traen de serie, no necesitas instalar nada. Es tan básico que viene incluido en la librería estándar de prácticamente cualquier lenguaje.
¿Qué problema tiene usar btoa() directamente con emojis o caracteres especiales en el navegador?
🔗 6. Base64 vs Base64URL
Aquí hay un matiz que mucha gente se come y es que existen dos variantes de Base64:
Usa + y / como caracteres extra. Incluye = como padding. Es el que se usa en emails (MIME), Data URIs y la mayoría de APIs.
Sustituye + por - y / por _. Normalmente omite el padding (=). Es el que usan los JWT y cualquier dato que viaje en URLs, porque + y / tienen significado especial en las URLs.
¿Por qué? Porque el + en una URL significa “espacio” y el / separa rutas. Si metes Base64 estándar en una URL, se rompe todo. Base64URL resuelve esto cambiando esos dos caracteres problemáticos.
// Base64 estándar
'SGVsbG8rV29ybGQ/'; // Tiene + y /
// Base64URL (seguro para URLs)
'SGVsbG8tV29ybGRf'; // Usa - y _
Si usas JWT (JSON Web Tokens), ya estás usando Base64URL sin saberlo. Cada token JWT tiene tres partes separadas por puntos, y cada parte es Base64URL:
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZG9taW4ifQ.K7qMZu2Gq8VpN5...
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
Header Payload Signature
(Base64URL) (Base64URL) (Base64URL)
¿Cuál es la diferencia principal entre Base64 estándar y Base64URL?
🤔 7. ¿Para qué se usa hoy en día?
Aunque los correos modernos son más listos, Base64 sigue siendo muy importante en el desarrollo web.
Data URIs (Imágenes en línea)
Puedes incrustar imágenes pequeñas directamente en tu CSS o HTML sin hacer una petición HTTP extra al servidor.
/* El icono está escrito directamente en el CSS */
.icono-flecha {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...');
}
Esto es útil para iconos muy pequeños (favicons, spinners, flechitas). Para imágenes grandes es mala idea porque el 33% extra de tamaño más la pérdida de caché del navegador hacen que sea contraproducente.
JWT (JSON Web Tokens)
Si usas autenticación moderna, usas JWT. Un token JWT son tres partes separadas por puntos. ¿Adivinas qué codificación usan esas partes para viajar en la cabecera HTTP? Pozi, Base64URL.
Canvas y manipulación de imágenes
Cuando manipulas imágenes en el <canvas> de HTML5 y quieres guardar el resultado, el navegador te devuelve una cadena Base64:
const canvas = document.getElementById('miCanvas');
const dataURL = canvas.toDataURL('image/png');
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
// Puedes meter esto en un <img> directamente
document.getElementById('preview').src = dataURL;
// O enviarlo al servidor por AJAX
fetch('/api/guardar-imagen', {
method: 'POST',
body: JSON.stringify({ imagen: dataURL }),
});
APIs y transporte de datos
Muchas APIs envían archivos binarios dentro de JSON usando Base64. Por ejemplo, la API de GitHub devuelve el contenido de los archivos codificado en Base64:
{
"name": "README.md",
"content": "IyBNaSBwcm95ZWN0bwoKRXN0ZSBlcyBtaSByZXBvc2l0b3Jpbw==",
"encoding": "base64"
}
¿Cuál es un caso de uso real y válido de Base64 en desarrollo web?
⚠️ 8. Lo que NO es Base64
Esto es tan importante que merece su propia sección.
Base64 NO es encriptación
Este es el error más común. Codificar una contraseña en Base64 no la protege. Cualquiera puede hacer “copiar-pegar” en un decodificador online y ver el contenido. Es como escribir un secreto en otro idioma: no es secreto, solo está traducido.
Para que quede claro:
- Codificación (Base64): transforma datos para que sean compatibles con un medio de transporte. Es reversible por diseño. No necesitas clave.
- Hashing (bcrypt, SHA-256): genera un resumen irreversible de los datos. No puedes recuperar el original. Se usa para almacenar contraseñas.
- Encriptación (AES, RSA): transforma datos para que solo quien tiene la clave pueda leerlos. Es reversible, pero solo con la clave.
Si guardas contraseñas en Base64, cualquier atacante que acceda a tu base de datos las decodifica en 2 segundos. Usa bcrypt o argon2 para contraseñas. Y yasta!.
¿Por qué NO deberías almacenar contraseñas codificadas en Base64?
📈 9. Cuándo sí y cuándo no
- Incrustar iconos pequeños en CSS/HTML (Data URIs)
- Enviar archivos binarios dentro de JSON por una API
- Transportar datos en protocolos que solo aceptan texto
- Adjuntos de email (MIME)
- Tokens JWT (Base64URL)
- Seguridad o encriptación — no protege nada
- Imágenes grandes — el 33% extra de peso es un crimen
- Vídeos o archivos pesados — usa multipart/form-data
- Comprimir datos — Base64 hace lo opuesto, agranda
- Ofuscar código — es trivial de decodificar
🐛 10. Errores comunes
1. Usar Base64 para “proteger” datos. Base64 no es seguridad. Es como poner un cartel en otro idioma y creer que nadie lo va a traducir.
2. Codificar imágenes grandes en Base64 para meterlas en CSS. Una imagen de 500KB se convierte en ~667KB de texto Base64, y encima el navegador no la puede cachear por separado. Para imágenes de más de 2-3KB, usa archivos normales.
3. No manejar bien UTF-8 con btoa(). La función btoa() del navegador solo acepta caracteres Latin-1. Si le pasas un emoji o una ñ directamente, peta. Necesitas pasar por encodeURIComponent primero (como vimos en los ejemplos de arriba).
4. Confundir Base64 con Base64URL. Si usas Base64 estándar en una URL, los + se convierten en espacios y los / en separadores de ruta. Si estás trabajando con JWT o URLs, usa Base64URL.
5. No quitar el padding al comparar. Algunos sistemas omiten el = del final y otros no. SG9sYQ== y SG9sYQ son la misma cadena decodificada, pero como strings son diferentes. Tenlo en cuenta al comparar.
🖼️ 11. El Resumen Memorable
Base64 es como triturar tu comida (datos binarios) para meterla en un tupper (caracteres ASCII) y enviarla por correo. Al llegar, alguien junta los trocitos y recrea el plato original. Ocupa más espacio, pero te aseguras de que no se derrame por el camino.
Lo que hay que quedarse:
- 64 caracteres seguros: A-Z, a-z, 0-9, +, /
- 3 bytes → 4 caracteres (por eso crece un 33%)
- El
=es padding, relleno para completar el último bloque - No es seguridad, es transporte
- Base64URL cambia
+y/por-y_para viajar en URLs
¡EA! Ya sabes que esos chorizos de letras aleatorias tienen sentido. Saluditos y a seguir programando con una birrita 🍻