Herramientas para desarrolladores

Qué es Base64, cuándo usarlo y cómo codificar en JavaScript, Node y la terminal

Base64 convierte binarios en texto para transportarlos. Qué es, cuánto aumenta el tamaño, cómo codificar en JavaScript, Node.js y la terminal, y por qué no cifra.

Base64 es una forma de representar datos binarios (una imagen, un PDF, bytes arbitrarios) usando solo 64 caracteres de texto imprimible: las letras A-Z y a-z, los dígitos 0-9 y los símbolos + y /, con = como relleno. Sirve para transportar binarios por canales pensados para texto, como JSON, correo electrónico, URLs o atributos HTML. Aumenta el tamaño aproximadamente un 33 % y no es cifrado: cualquiera puede decodificarlo.

Este artículo explica cómo funciona, cuándo tiene sentido usarlo (y cuándo no) y cómo codificar y decodificar correctamente en JavaScript, Node.js y la terminal, incluido el caso de los caracteres no ASCII que hace fallar a btoa.

Cómo funciona

Base64 toma los datos de 3 en 3 bytes (24 bits) y los reparte en 4 grupos de 6 bits. Cada grupo de 6 bits (un valor de 0 a 63) se sustituye por un carácter de la tabla. Si la longitud no es múltiplo de 3, se añaden uno o dos = al final para completar el último bloque.

De ahí sale el coste: cada 3 bytes se convierten en 4 caracteres, así que el resultado ocupa 4/3 del original (un 33 % más), redondeado hacia arriba al múltiplo de 4. Por ejemplo, la cadena Año 2026 ñ ocupa 12 bytes en UTF-8 y su Base64, QcOxbyAyMDI2IMOx, tiene 16 caracteres.

La especificación completa es el RFC 4648, que define también la variante URL-safe: sustituye + por - y / por _ para que el resultado pueda ir en una URL o un nombre de archivo sin escapes. Los tokens JWT usan esta variante, normalmente sin relleno.

Cuándo usar Base64

  • Incrustar un recurso pequeño en HTML, CSS o JSON: un icono SVG o PNG de unos pocos KB como data URL evita una petición HTTP.
  • Enviar binarios en una API JSON cuando no puedes usar multipart/form-data.
  • Adjuntos de correo: el estándar MIME codifica los adjuntos en Base64 porque el correo es un protocolo de texto.
  • Autenticación HTTP básica: la cabecera Authorization: Basic ... lleva usuario:contraseña en Base64. Esto no lo protege: por eso solo tiene sentido sobre HTTPS.
  • Claves y certificados en formato PEM, que son Base64 entre líneas -----BEGIN ... -----.

Cuándo no usarlo

  • Para “ocultar” información. Base64 se decodifica con una línea de código. Si necesitas confidencialidad, cifra.
  • Para imágenes grandes en HTML. Una foto de 300 KB en Base64 pasa a 400 KB, no se cachea por separado y bloquea el parseo del HTML. Por encima de unos pocos KB, sirve el archivo con su propia URL (y conviértelo a WebP).
  • Para texto normal en JSON. JSON ya transporta texto Unicode; codificarlo en Base64 solo añade un 33 % de peso.

Codificar y decodificar

En el navegador: btoa y atob (con cuidado)

btoa() y atob() trabajan con cadenas de bytes Latin-1, no con texto Unicode. Con caracteres fuera de ese rango (una ñ funciona, un emoji o caracteres asiáticos no) btoa lanza InvalidCharacterError. La forma correcta es pasar primero por TextEncoder:

// Codificar texto UTF-8 a Base64
function toBase64(texto) {
  const bytes = new TextEncoder().encode(texto);
  let binario = '';
  for (const b of bytes) binario += String.fromCharCode(b);
  return btoa(binario);
}

// Decodificar Base64 a texto UTF-8
function fromBase64(b64) {
  const binario = atob(b64);
  const bytes = Uint8Array.from(binario, (c) => c.charCodeAt(0));
  return new TextDecoder().decode(bytes);
}

toBase64('Año 2026 ñ'); // "QcOxbyAyMDI2IMOx"
fromBase64('QcOxbyAyMDI2IMOx'); // "Año 2026 ñ"

Para archivos (por ejemplo, una imagen seleccionada por el usuario) usa FileReader.readAsDataURL(), que devuelve directamente una data URL con el contenido en Base64.

En Node.js: Buffer

const b64 = Buffer.from('Año 2026 ñ', 'utf8').toString('base64'); // "QcOxbyAyMDI2IMOx"
const texto = Buffer.from(b64, 'base64').toString('utf8'); // "Año 2026 ñ"

// Variante URL-safe (sin + / =)
const urlSafe = Buffer.from('Año 2026 ñ').toString('base64url');

// Un archivo completo
import { readFile } from 'node:fs/promises';
const png = await readFile('icono.png');
const dataUrl = `data:image/png;base64,${png.toString('base64')}`;

Buffer gestiona la codificación de caracteres correctamente, así que no hay que hacer el rodeo de TextEncoder.

En la terminal

# Codificar un archivo (GNU coreutils, Linux)
base64 imagen.png > imagen.b64

# Decodificar
base64 -d imagen.b64 > imagen.png

# Codificar una cadena sin el salto de línea final
printf 'Año 2026 ñ' | base64

En macOS la opción de decodificar es -D en versiones antiguas y -d o --decode en las recientes. Por defecto, la herramienta de GNU parte la salida en líneas de 76 caracteres; -w 0 lo evita.

Sin instalar nada

Para una conversión puntual, las herramientas de texto de AIMRAN Tools permiten codificar y decodificar Base64 en el navegador, sin enviar el contenido a ningún servidor. Es la opción cómoda para inspeccionar un token, un adjunto o una data URL.

Data URLs

Una data URL incrusta el contenido en la propia dirección: data:[tipo MIME][;base64],datos.

<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PC9zdmc+" alt="" width="10" height="10" />

Útiles para iconos pequeños y fondos CSS mínimos. Para SVG, a menudo es más compacto incrustarlo como texto con escape de URL que en Base64.

Errores habituales

  1. Usar btoa con texto Unicode sin pasar por TextEncoder: InvalidCharacterError.
  2. Olvidar el tipo MIME en una data URL: el navegador no sabe qué hacer con los bytes.
  3. Mezclar la variante estándar y la URL-safe: un + decodificado como - corrompe los datos. Usa la misma variante en ambos extremos.
  4. Tratar Base64 como seguridad: credenciales “codificadas” en un archivo público son credenciales públicas.
  5. Incrustar recursos grandes: más peso, sin caché y HTML más lento de parsear.

Conclusión

Base64 resuelve un problema concreto: mover bytes por un canal de texto. Hazlo con Buffer en Node.js, con TextEncoder + btoa en el navegador o con base64 en la terminal, usa la variante URL-safe cuando el resultado vaya en una URL, y recuerda sus dos límites: aumenta el tamaño un tercio y no protege nada.

Fuentes y referencias

  1. RFC 4648: The Base16, Base32, and Base64 Data Encodings rfc-editor.org
  2. MDN: Base64 developer.mozilla.org
  3. MDN: btoa() developer.mozilla.org
  4. Node.js: Buffer nodejs.org
  5. MDN: Data URLs developer.mozilla.org

Herramientas relacionadas

Herramientas gratuitas de AIMRAN Tools que funcionan en tu navegador, sin registro.

Ver todas las herramientas

Herramientas para desarrolladores

Cómo validar un JSON y entender sus errores más habituales

Reglas de sintaxis de JSON según el estándar, los cinco errores que causan casi todos los fallos de parseo y cómo validar desde el navegador, la terminal o Node.js.

4 min de lectura