Base64 explicado: agrupación de 6 bits, ~33% de inflación de tamaño, relleno y base64url vs estándar

Qué es Base64 — y qué no es

Base64 es un esquema de codificación de binario a texto. Convierte datos binarios arbitrarios en una cadena de caracteres ASCII imprimibles, haciendo que esos datos sean seguros para incrustar en contextos diseñados para texto legible por humanos. Base64 no es compresión — hace los datos más grandes. No es cifrado — cualquiera que tenga la cadena codificada puede recuperar los bytes originales trivialmente. El nombre proviene del hecho de que utiliza un alfabeto de exactamente 64 caracteres, elegido porque 2⁶ = 64 permite que cada carácter represente exactamente 6 bits de entrada.

Base64 no fue inventado como un estándar independiente; surgió de la necesidad de enviar archivos adjuntos de correo electrónico binarios a través de infraestructura SMTP que solo transmitía de manera confiable ASCII de 7 bits. RFC 2045 (1996), que define MIME, estandarizó la codificación para el correo electrónico. Una década después, RFC 4648 (2006) consolidó base64 y sus variantes — incluyendo base32 y base64url — en un único documento de referencia. RFC 4648 sigue siendo la especificación autorizada utilizada hoy en día por cualquier nuevo protocolo que necesite una codificación de binario a texto.

La agrupación de 6 bits: cómo tres bytes de entrada se convierten en cuatro caracteres

El núcleo de base64 es una operación simple de reempaquetado de bits. Los datos binarios llegan en grupos de bytes de 8 bits; base64 reagrupa esos bits en fragmentos de 6 bits, cada uno de los cuales se mapea a un carácter en el alfabeto de 64 caracteres. Dado que el mínimo común múltiplo de 6 y 8 es 24, la unidad de procesamiento natural es 3 bytes = 24 bits → 4 caracteres. Tomando Man como ejemplo concreto: los tres bytes son 0x4D, 0x61, 0x6E, dando la secuencia de bits 01001101 01100001 01101110. Reagrupados en cuatro valores de 6 bits: 010011 (19 → T), 010110 (22 → W), 000101 (5 → F), 101110 (46 → u). El resultado codificado es TWFu.

Esta relación de 3 a 4 bytes es la fuente directa de la inflación de tamaño. Por cada 3 bytes de entrada, la salida siempre son 4 caracteres independientemente de los valores reales de bytes. Para n bytes de entrada, la salida codificada es ceil(n / 3) × 4 caracteres, lo que significa que la salida es siempre un 33% más grande que la entrada (exactamente 4/3 veces más grande). Un archivo de 1 KB se codifica a aproximadamente 1,37 KB; una imagen de 1 MB se codifica a aproximadamente 1,37 MB.

El alfabeto: A–Z, a–z, 0–9, +, /

El alfabeto base64 estándar mapea los valores de 6 bits 0–63 a caracteres ASCII imprimibles en este orden: los valores 0–25 mapean a AZ mayúsculas, los valores 26–51 mapean a az minúsculas, los valores 52–61 mapean a dígitos 09, el valor 62 mapea a +, y el valor 63 mapea a /. Este ordenamiento coloca las letras antes que los dígitos por razones históricas de compatibilidad MIME. La elección de + y / para los últimos dos valores ha causado décadas de problemas de interoperabilidad, ya que ambos caracteres tienen significado especial en las URLs.

Un error común es creer que base64 es independiente del conjunto de caracteres. No lo es: el alfabeto es ASCII fijo. Un decodificador que encuentre un carácter fuera del conjunto de 65 caracteres (64 caracteres de datos más = para relleno) debe rechazar la entrada u omitirla según el contexto de la especificación. RFC 4648 recomienda rechazar los caracteres que no pertenecen al alfabeto en modo estricto. El signo igual = es un centinela, no un carácter de datos — marca el relleno y nunca debe aparecer excepto al final de una cadena codificada.

Relleno: por qué existen los signos de igual y cuándo se pueden omitir

Dado que la codificación procesa 3 bytes a la vez, las entradas cuya longitud no es divisible por 3 dejan un grupo parcial al final. El relleno resuelve esto: fuerza que la salida codificada sea siempre un múltiplo de 4 caracteres, lo que permite calcular el recuento de bytes original solo a partir de la longitud de salida. Si la entrada tiene 1 byte restante, se añaden 2 caracteres de relleno ==. Si la entrada tiene 2 bytes restantes, se añade 1 carácter de relleno =.

El relleno es opcional en contextos donde la longitud total se conoce por otros medios. RFC 7515, la especificación de JSON Web Signature, requiere explícitamente que las implementaciones omitan el relleno = al codificar componentes JWT, porque los puntos entre las tres partes de un JWT ya delimitan los segmentos. Por lo tanto, los valores codificados en base64url en los JWT nunca terminan en =. Restaurar el relleno es sencillo: añadir caracteres = hasta que la longitud de la cadena sea un múltiplo de 4. La mayoría de las bibliotecas base64 modernas aceptan tanto entradas con relleno como sin él.

Base64url: la variante URL-segura usada en JWTs y tokens OAuth

Los caracteres + y / del base64 estándar son problemáticos en contextos URL. Un + en una cadena de consulta se interpreta como un espacio bajo la codificación application/x-www-form-urlencoded. Un / es un separador de segmento de ruta. Base64url, definido en RFC 4648 Sección 5, reemplaza + por - y / por _. Estos dos caracteres son seguros en URLs sin codificación porcentual. El relleno = también se omite típicamente en contextos base64url.

Base64url se usa donde se necesita una representación binaria compacta y URL-segura: las secciones de encabezado y carga útil de un JWT son JSON codificado en base64url; los códigos de autorización OAuth 2.0 son a menudo bytes aleatorios codificados en base64url; los verificadores y desafíos de código PKCE (RFC 7636) usan base64url. La relación de inflación de datos es idéntica al base64 estándar — exactamente 4/3 — porque solo difiere el alfabeto, no el algoritmo de agrupación de bits.

Impacto práctico en el tamaño y cómo elegir entre base64 y binario

La sobrecarga del ~33% es el principal costo práctico de base64. Para las URI de datos — incrustar imágenes, fuentes o SVGs directamente en HTML o CSS con data:image/png;base64,... — la compensación es eliminar un viaje de ida y vuelta HTTP a costa de un documento más grande. Esto es beneficioso para recursos pequeños (típicamente menos de 4–8 KB): el viaje de ida y vuelta ahorrado supera el aumento de tamaño. Para recursos más grandes, el aumento de tamaño degrada el rendimiento porque el documento HTML más grande tarda más en analizarse y no puede almacenarse en caché por separado.

La autenticación básica HTTP codifica las credenciales como base64(usuario:contraseña) en el encabezado Authorization: Basic .... Esto no es una medida de seguridad — el nombre de usuario y la contraseña son trivialmente recuperables mediante decodificación. La autenticación básica requiere HTTPS para ser segura; la codificación base64 existe solo porque la especificación de encabezados HTTP requiere ASCII imprimible. Si una carga útil contiene información sensible, base64 no es un sustituto del cifrado. Use cifrado autenticado (por ejemplo, AES-GCM) o JSON Web Encryption (JWE, RFC 7516) para datos confidenciales.