¿Qué es Base64? Cómo funciona, base64url, data URI y errores típicos

Base64 aparece en adjuntos de correo, tokens JWT, data URI y respuestas de API. Te explicamos cómo convierte 3 bytes en 4 caracteres, por qué engorda un tercio y qué errores lo rompen en proyectos reales.

10 min de lectura ToolsBasic
¿Qué es Base64? Cómo funciona, base64url, data URI y errores típicos

Base64 es un sistema de codificación que convierte cualquier secuencia de bytes (una imagen, un PDF, una clave) en texto formado solo por 64 caracteres seguros: letras, números, + y /. Cada 3 bytes se transforman en 4 caracteres, así que el resultado ocupa alrededor de un 33 % más. Si te preguntas qué es Base64 en una sola frase: es la forma estándar de meter datos binarios en canales que solo aceptan texto, como el correo, un JSON o una URL. No es cifrado, no usa clave y cualquiera puede revertirlo.

Para seguir los ejemplos, ten abierto el codificador y decodificador Base64. Si el valor va a terminar en una dirección web, el codificador de URL se encarga de los caracteres reservados; para leer el JSON que aparece al decodificar un token, usa el formateador JSON; antes de incrustar una imagen conviene pasarla por el compresor de imágenes, y el contador de caracteres te dice cuánto mide exactamente el resultado.

¿Qué es Base64 y de dónde sale?

El correo electrónico nació para transportar texto ASCII de 7 bits. Muchos servidores intermedios eliminaban el octavo bit, cortaban líneas largas o se atragantaban con caracteres de control, de modo que enviar un archivo binario tal cual era una lotería. La norma MIME (RFC 2045, de 1996) resolvió el problema traduciendo los adjuntos a un alfabeto reducido que ningún servidor alteraba. Hoy la definición de referencia para cualquier uso está en el RFC 4648.

El problema de fondo sigue vivo con otros nombres. JSON no tiene un tipo para bytes. HTML y CSS son texto. Las cabeceras HTTP también. Cada vez que hay que colar datos binarios por uno de esos caminos, esta codificación aparece como solución por defecto.

El alfabeto y el relleno

Cada carácter representa un número de 6 bits, de 0 a 63, en un orden fijo: A–Z para 0–25, a–z para 26–51, 0–9 para 52–61, + para 62 y / para 63. El signo = no forma parte del alfabeto: es relleno y no transporta información. La ñ no aparece porque no hace falta; lo que se codifica son bytes, no letras.

Cómo funciona: de 3 bytes a 4 caracteres

Codificar a mano la palabra Sol deja ver todo el mecanismo:

  1. Anota el valor de cada byte: S = 83, o = 111, l = 108.
  2. Pásalos a binario: 01010011 01101111 01101100.
  3. Reparte los 24 bits en cuatro grupos de 6: 010100 110110 111101 101100.
  4. Convierte cada grupo a decimal: 20, 54, 61, 44.
  5. Búscalos en el alfabeto: U, 2, 9, s. El resultado es U29s.

Como 24 es divisible entre 8 y entre 6, tres bytes siempre caben exactos en cuatro caracteres. Decodificar es recorrer el mismo camino al revés: cada carácter vuelve a ser 6 bits y cada cuatro caracteres, tres bytes.

Cuándo aparecen los signos =

Si la entrada no es múltiplo de tres, el último grupo se completa con bits a cero y la salida se rellena con = hasta un múltiplo de cuatro:

TextoBytesResultadoRelleno
Sol3U29sNinguno
So2U28=Un signo
S1Uw==Dos signos

Nunca verás tres signos de relleno. Y si la longitud de una cadena, dividida entre 4, deja resto 1, la cadena está rota: casi siempre falta un carácter que se perdió al copiar o al guardarla en una columna demasiado corta.

Tildes, eñes y UTF-8

Lo que se codifica son los bytes del texto, y en UTF-8 la ñ o la á ocupan dos. Por eso ñandú, con cinco letras, son siete bytes y da w7FhbmTDug==. Si quien codifica usa UTF-8 y quien decodifica interpreta los bytes como Windows-1252, la palabra España vuelve convertida en España. Ese fallo no es culpa del algoritmo: son dos sistemas que no se han puesto de acuerdo en la codificación de caracteres.

Cuánto engorda: el 33 % y sus alternativas

La longitud de salida es 4 × ⌈n / 3⌉ caracteres para n bytes. Una imagen de 90 KB se convierte en unos 120 KB de texto. En el correo, MIME añade además un salto de línea cada 76 caracteres y el sobrecoste ronda el 37 %. No es el único esquema de su clase:

EsquemaProporciónAumentoDónde se usa
Hexadecimal (Base16)2 caracteres por byte100 %Hashes y sumas de verificación
Base328 caracteres por cada 5 bytes60 %Claves de apps de autenticación
Base644 caracteres por cada 3 bytesAlrededor del 33 %Correo, JSON, JWT, data URI
Ascii855 caracteres por cada 4 bytes25 %Flujos de PDF y PostScript

Su éxito se debe a la sencillez y a que todos los lenguajes lo traen de serie, no a la eficiencia. La compresión HTTP recupera parte del exceso, pero si codificas un JPEG o un ZIP, que ya vienen comprimidos, casi todo el sobrecoste se queda. Un archivo grande se envía como archivo.

Base64url: la variante para URLs y nombres de archivo

Dos caracteres del alfabeto estándar dan guerra en la web: la barra separa rutas y el signo más, en un formulario codificado, se lee como espacio. La sección 5 del RFC 4648 define base64url para evitarlo: - sustituye a +, _ sustituye a / y el relleno suele omitirse.

Con el texto <<???>> se ve claro: en el alfabeto estándar es PDw/Pz8+Pg== y en base64url, PDw_Pz8-Pg. Si metes la forma estándar en un parámetro sin escaparla, el servidor puede recibir un espacio donde había un más. O usas base64url o la codificas antes para URL, y entonces queda PDw%2FPz8%2BPg%3D%3D.

Los JSON Web Tokens (JWT) son el caso más conocido. Las dos primeras partes de un token, separadas por puntos, son JSON en base64url sin relleno. Decodifica eyJzdWIiOiI0MiIsInJvbCI6ImFkbWluIn0 y obtendrás {"sub":"42","rol":"admin"}. Por eso tantos tokens empiezan por eyJ: es lo que queda de la apertura {" de un objeto JSON cuando la sigue una letra.

Qué es Base64 en la práctica: dónde lo vas a encontrar

  • Adjuntos de correo. Abre el código fuente de cualquier mensaje con un PDF y verás bloques de texto bajo la cabecera Content-Transfer-Encoding: base64.
  • Data URI. El formato data:[tipo][;base64],datos (RFC 2397) incrusta un archivo dentro de HTML o CSS. Todo PNG codificado empieza por iVBORw0KGgo, que es su firma fija de 8 bytes.
  • Certificados y claves. Los archivos PEM son texto codificado en líneas de 64 caracteres entre cabeceras -----BEGIN y -----END.
  • APIs. Cuando un servicio devuelve una imagen o un documento dentro de un JSON, casi siempre viaja como una cadena codificada.

Sobre los data URI, una advertencia práctica. Ahorran una petición, pero el archivo crece un tercio, el navegador no puede cachearlo por separado y viaja de nuevo con cada copia del HTML o del CSS que lo contiene. Una imagen grande incrustada en la hoja de estilos retrasa además el pintado de la página hasta que llega el CSS completo. Tiene sentido para iconos de pocos kilobytes, mejor comprimidos antes de codificarlos. Para iconos SVG, el texto codificado para URL (data:image/svg+xml,...) suele salir más corto, porque SVG ya es texto.

No es cifrado: lo que esta codificación no protege

Esta confusión sale cara. Codificar cambia la forma de los datos, no los oculta. No hay clave ni parámetro secreto, y cualquier lenguaje lo revierte con una sola llamada.

La autenticación HTTP Basic lo demuestra. El navegador une usuario y contraseña con dos puntos, lo codifica y lo manda en una cabecera (RFC 7617). El par usuario:clave viaja como Authorization: Basic dXN1YXJpbzpjbGF2ZQ==, y quien vea esa cabecera lee la contraseña al instante. Lo que la protege es HTTPS, no la codificación.

  • Si necesitas confidencialidad, usa cifrado de verdad, como AES, con una clave bien custodiada.
  • Si guardas contraseñas, usa un hash lento e irreversible como bcrypt o Argon2. Una contraseña codificada es, a efectos prácticos, una contraseña en texto plano.
  • Si necesitas detectar manipulaciones, usa una firma o un HMAC, que es justo lo que hace la tercera parte de un JWT.

Errores típicos y cómo resolverlos

  • btoa() con tildes. En el navegador, btoa("ñ") lanza InvalidCharacterError porque solo admite caracteres Latin-1. Hay que convertir antes el texto a bytes UTF-8 con TextEncoder; la herramienta de este sitio ya lo hace por ti.
  • El salto de línea de echo. echo "hola" | base64 devuelve aG9sYQo= y no aG9sYQ==, porque echo añade un salto de línea que también se codifica. Usa printf '%s' hola | base64. Este detalle provoca errores de clave de API inválida que parecen imposibles.
  • Líneas cortadas. GNU base64 corta cada 76 caracteres salvo que pases -w 0, y los PEM usan 64. Algunos decodificadores estrictos rechazan esos saltos.
  • Relleno ausente. Si una librería exige relleno y recibe base64url, añade = hasta que la longitud sea múltiplo de 4.
  • El más convertido en espacio. Un valor estándar pegado en una URL sin escapar llega con espacios donde había signos más.
  • Datos binarios leídos como texto. Decodificar una imagen y mostrarla como texto produce basura. La herramienta avisa cuando el resultado no es texto UTF-8 válido.

Cómo usar el codificador paso a paso

  1. Pega el texto o la cadena codificada en el campo de entrada.
  2. Elige el modo: Automático, Codificar o Decodificar. El automático solo decodifica lo que de verdad parece codificado y da texto legible; todo lo demás lo codifica.
  3. Fuerza la dirección con valores cortos y ambiguos: QUFB parece una sigla cualquiera, pero también es la codificación válida de AAA, y el modo automático la decodifica.
  4. Copia el resultado. Al decodificar se aceptan base64url (con - y _, con o sin relleno) y el formato MIME repartido en varias líneas.

Todo ocurre en tu navegador: lo que escribes no se envía al servidor y la página solo suma un contador de uso anónimo. Aun así, conviene no pegar claves de producción en formularios web que no controlas.

Preguntas frecuentes

¿Por qué algunas cadenas terminan en = o ==?

Es el relleno. Si la entrada no es múltiplo de 3 bytes, la salida se completa hasta un múltiplo de 4 caracteres. Un signo indica que el último bloque tenía dos bytes; dos signos, que tenía uno. Formatos como JWT lo eliminan por completo.

¿Base64 sirve para comprimir?

No. Hace lo contrario: el resultado ocupa unos cuatro tercios del original. Para reducir tamaño hay que comprimir (gzip, ZIP o un formato de imagen más eficiente) y codificar después solo si el canal exige texto.

¿Es seguro guardar una contraseña codificada así?

No. Equivale a guardarla en texto plano, porque cualquiera la decodifica en un segundo. Las contraseñas se guardan con un hash irreversible diseñado para ello.

¿Cómo sé si una cadena está en Base64?

Fíjate en que la longitud sea múltiplo de 4, que solo use caracteres del alfabeto y que tenga como mucho dos signos = al final. Aun así, la única prueba real es decodificarla y ver si el resultado tiene sentido: muchas palabras normales pasan el filtro por casualidad.

Si lo que buscas es que tus archivos pesen menos, lee qué es minificar código y en qué se diferencia de gzip. En qué es un UUID verás cómo base64url reduce un identificador de 16 bytes a 22 caracteres. Para el JSON que suele envolver estos campos tienes la guía trabajar con datos JSON, y si vas a incrustar iconos vectoriales, conviene repasar qué es un archivo SVG.

Herramientas relacionadas

Catálogo

Artículos del blog