[COMPARAR] Base64 vs Base64URL vs Base32
Tres codificaciones, un RFC. Esto es lo que realmente difiere — alfabeto, sobrecosto, legibilidad, sensibilidad a mayúsculas — y cómo elegir la correcta para URLs, nombres de archivo, correos, códigos QR y códigos pronunciados por humanos.
// LA TABLA COMPARATIVA RÁPIDA
Base64 Base64URL Base32
(RFC 4648 §4) (RFC 4648 §5) (RFC 4648 §6)
────────────────────────────────────────────────────────────────
Alphabet size 64 64 32
Bits per char 6 6 5
Characters used A-Z a-z 0-9 A-Z a-z 0-9 A-Z 2-7
+ / - _ (+ = for pad)
Padding = (required) = (optional) = (optional)
Case-sensitive Yes Yes No (A = a)
Size overhead ~33% ~33% ~60%
URL-safe No Yes Yes
Filename-safe No Yes Yes
DNS-safe No Yes Yes
Human-readable Medium Medium High
Human-spoken Painful Painful Doable
QR-code friendly OK OK Excellent
(alphanumeric) (alphanumeric) (alphanumeric mode)
// LO QUE TIENEN EN COMÚN
Las tres están definidas en RFC 4648 — un único documento de 2006 que unificó la familia de "codificaciones binario-a-texto base-N". Comparten el mismo algoritmo subyacente: tomar entrada binaria, reagrupar los bits en fragmentos de log₂(tamaño del alfabeto), asignar cada fragmento a un carácter, rellenar para alinear en el límite de palabra de salida.
• Base64: fragmentos de 6 bits → 4 caracteres por 3 bytes (proporción 4/3, ~33% más grande)
• Base32: fragmentos de 5 bits → 8 caracteres por 5 bytes (proporción 8/5, ~60% más grande)
• Base16 (hex): fragmentos de 4 bits → 2 caracteres por 1 byte (proporción 2/1, 100% más grande)
Las tres son reversibles, deterministas y preservan cada byte de entrada. Son codificaciones, no compresión y no cifrado. Cualquiera con la cadena puede decodificarla de vuelta.
// CUÁNDO ELEGIR BASE64 (ESTÁNDAR, §4)
Base64 estándar es el predeterminado para cualquier canal de texto que no sea una URL. Los cuerpos de correo MIME, certificados envueltos en PEM, HTTP Basic Auth, S/MIME, XML-DSIG, data URIs, y la mayoría de los contenedores de formato de archivo de binario-en-texto lo usan. Los caracteres + / = son todos seguros dentro de valores de atributos entre comillas, dentro de encabezados de correo electrónico (cuando hay saltos de línea) y dentro de cadenas XML/JSON.
Usa Base64 estándar cuando el consumidor aguas abajo sea un protocolo de texto que acepte ASCII imprimible arbitrario — y especialmente cuando las especificaciones a nivel de RFC lo mencionen explícitamente (MIME: RFC 2045; PEM: RFC 7468; HTTP Basic Auth: RFC 7617; data URI: RFC 2397).
- > Adjuntos de correo electrónico (codificación de transferencia base64 MIME)
- > Certificados PEM, claves, CRLs (-----BEGIN ... -----)
- > Valor del encabezado HTTP Basic Authentication
- > Data URIs: data:image/png;base64,...
- > Cargas S/MIME y XML-ENC
- > Firmas clásicas SOAP / XML-DSIG
- > Cualquier campo binario dentro de un documento JSON que no se coloque luego en una URL
// CUÁNDO ELEGIR BASE64URL (§5)
En el momento en que tu salida Base64 toque una URL, un valor de cookie, un nombre de archivo, una etiqueta DNS, o cualquier lugar donde + / = necesitarían codificación por porcentaje, cambia a Base64URL. Usa el mismo alfabeto de 64 caracteres con dos intercambios (+ → -, / → _) y convencionalmente descarta el relleno.
- > Tokens JWT — encabezado, carga, firma son todos base64url (RFC 7515)
- > code_challenge de OAuth 2.0 PKCE (RFC 7636)
- > Parámetros state y nonce de OpenID Connect
- > Enlaces mágicos, tokens de invitación, tokens de restablecimiento de contraseña
- > Valores de cookies que pueden copiarse en URLs
- > Nombres de archivo derivados de hashes — evita / en nombres de archivo
- > Etiquetas DNS, registros TXT — guiones permitidos, barras no
- > Claves de almacenamiento direccionable por contenido
- > Identificadores de URL cortos generados a partir de bytes aleatorios
// CUÁNDO ELEGIR BASE32 (§6)
Base32 utiliza solo 32 caracteres: mayúsculas A–Z y dígitos 2–7. Eso es ~60% de sobrecosto de tamaño — mucho peor que Base64 — pero ganas tres propiedades muy específicas que Base64 no puede igualar.
Insensibilidad a mayúsculas. El alfabeto es solo mayúsculas. Los humanos leyendo o escribiendo la cadena pueden ignorar las mayúsculas; JBSWY3DP y jbswy3dp se decodifican de forma idéntica.
Caracteres desambiguados. Los dígitos 0, 1, 8 y 9 se excluyen porque se parecen a O, I, B y g en fuentes comunes. Solo se usan 2–7. Esto hace que la transcripción humana desde una página impresa o una pantalla de teléfono sea mucho más confiable.
Compatibilidad con el modo alfanumérico de códigos QR. Los códigos QR tienen un modo especial "alfanumérico" que codifica 5.5 bits por carácter usando un subconjunto de ASCII. Base32 cabe completamente dentro de ese subconjunto (más el relleno), por lo que una cadena Base32 codificada en QR es significativamente más pequeña que una cadena Base64 codificada en QR.
- > Semillas secretas TOTP / HOTP — Google Authenticator, 1Password, Authy todos usan Base32
- > Direcciones Tor .onion v3 — codificaciones Base32 de 56 caracteres de claves ed25519
- > Info-hashes de BitTorrent compartidos como magnet links
- > Códigos de ubicación tipo geohash compartibles por humanos
- > Claves de licencia y números de serie de productos
- > Códigos de recuperación impresos (códigos de respaldo 2FA, mnemónicos de billeteras)
- > Transcripción tipo DTMF sobre canales de voz
- > Sistemas que necesitan almacenamiento insensible a mayúsculas (etiquetas DNS)
// SOBRECOSTO DE TAMAÑO — UN EJEMPLO CONCRETO
// Input: a 32-byte SHA-256 hash
// Raw: 0x89abcdef… (32 bytes, binary — can't put in text)
// Hex (Base16): 40b2e2… (64 chars, 100% overhead)
// Base32: 5ENM4H2TQWMZ3O4OQBJAFY5Q (56 chars, 75% overhead)
// Base64: ia+N7/eZtRsPj5TqFoqUlD… (44 chars, 37% overhead)
// Base64URL: ia-N7_eZtRsPj5TqFoqUlD… (43 chars, 34% overhead, no padding)
// Input: a 16-byte UUID
// Hex: e7a6c1d0-4b7d-4c6c-8e2f-9f1a3e4b5c6d (36 chars incl. dashes)
// Base32: 5WTMDUCLPVGGZDRPTF… (26 chars)
// Base64: 56bB0Et9TGyOL58aPktcbQ== (24 chars)
// Base64URL: 56bB0Et9TGyOL58aPktcbQ (22 chars, no padding)
// PRUEBA DE LEGIBILIDAD HUMANA
Aquí es donde Base32 brilla. Intenta leer estos en voz alta:
• a+b/c1D2e3F/+g= — Base64. "a minúscula, más, b minúscula, barra diagonal, c minúscula, uno, D mayúscula, dos, e minúscula, tres, F mayúscula, barra diagonal, más, g minúscula, igual." Propenso a errores de transcripción solo por las mayúsculas.
• JBSWY3DPEHPK3PXP — Base32. "J-B-S-W-Y, tres, D-P-E-H-P-K, tres, P-X-P." Las mayúsculas no importan. Sin ambigüedad de 0/O ni 1/l. Puedes leer esto por teléfono con alta confianza.
Esta es exactamente la razón por la que TOTP usa Base32: alguien tiene que escribir la semilla en su aplicación autenticadora desde una pantalla de respaldo del código QR. La sensibilidad a mayúsculas de Base64 generaría infinitos tickets de soporte.
// COMPARACIÓN DE TAMAÑO DE CÓDIGOS QR
Los códigos QR tienen un "modo alfanumérico" especial que empaca 5.5 bits por carácter usando un subconjunto de 45 caracteres: 0–9, A–Z (solo mayúsculas), espacio, y $ % * + - . / :. Cualquier cosa fuera de este subconjunto fuerza al código QR al "modo byte" que usa 8 bits por carácter — códigos QR significativamente más grandes.
Base32 está completamente dentro del subconjunto alfanumérico. Base64 no — las letras minúsculas y +/= fuerzan el modo byte (bueno, +/ están en el conjunto alfanumérico, pero cualquier minúscula fuerza el modo byte). Esto significa que una carga dada cabe en un código QR más pequeño cuando se codifica como Base32 — a menudo la diferencia entre un QR legible de 21×21 y uno abarrotado de 33×33.
// TRAMPAS AL DECODIFICAR
-
>
Sensibilidad a mayúsculas — los decodificadores Base64 rechazan entradas mal capitalizadas (
SGVsbG8=≠sgvSbg8=). Los decodificadores Base32 típicamente normalizan a mayúsculas antes de buscar, por lo que toleran cualquier caso. -
>
Relleno — Base64 estándar requiere relleno
=; JWT/base64url lo prohíbe; Base32 lo hace opcional (RFC 4648 §6). Siempre verifica qué espera tu decodificador. -
>
Espacios en blanco — MIME Base64 envuelve líneas a 76 columnas con CR-LF. Muchos decodificadores toleran espacios en blanco, algunos no. Elimínalos antes de pasar a
atob()o su equivalente. -
>
Colisiones de alfabeto — alimentar Base64 a un decodificador Base32 (o viceversa) parece que podría funcionar al principio —
A,B,Cson válidos en ambos — y luego falla silenciosamente cuando llega a+o=. - > Crockford Base32 es una variante no RFC usada por los IDs de Stripe y algunos sistemas blockchain. Usa un alfabeto diferente (excluyendo I, L, O, U) y soporta dígitos de verificación. No lo confundas con Base32 de RFC 4648.
- > Base32 Extended Hex (RFC 4648 §7) — un alfabeto Base32 alternativo que preserva el orden de clasificación lexicográfica. Usado en registros NSEC3 de DNSSEC. Fácil de confundir con Base32 estándar.
// UN DIAGRAMA DE FLUJO DE DECISIÓN
Does the output go into a URL, cookie, filename, DNS, JWT, or OAuth flow?
│
├─ Yes → Does a human need to type or speak the string?
│ │
│ ├─ Yes → Base32 (uppercase, no ambiguous chars)
│ │ e.g., TOTP seeds, recovery codes
│ │
│ └─ No → Base64URL (more compact, URL-safe)
│ e.g., JWT, short tokens, hash-named files
│
└─ No → Does the output go into a QR code that must stay tiny?
│
├─ Yes → Base32 (fits in QR alphanumeric mode)
│
└─ No → Standard Base64
e.g., email MIME, PEM, HTTP Basic, data URI
// ¿POR QUÉ NO BASE16 (HEX)?
Hexadecimal (RFC 4648 §8 lo llama Base16) es el fallback universal. Cada herramienta de shell, depurador y protocolo lo entiende. Es insensible a mayúsculas, trivialmente legible por humanos, y trivial de implementar. Pero duplica el tamaño de tu carga (100% de sobrecosto), por eso solo se usa para identificadores pequeños de longitud fija: hashes SHA-256 (64 caracteres hex = 32 bytes), UUIDs (32 caracteres hex = 16 bytes), direcciones MAC, direcciones de memoria en depuradores.
Para cualquier cosa más grande que unas pocas docenas de bytes, el costo de tamaño del hex es genuinamente doloroso sobre el cable. Base64 es 50% más pequeño que hex, Base32 es 25% más pequeño. Por eso Base64 ganó los casos de uso de correo electrónico e incrustación web, mientras que el hex se quedó en escenarios de depuración y visualización de hashes.
// ¿QUÉ HAY DE BASE58 / BASE62 / BASE85?
Existen codificaciones base-N no RFC para nichos específicos:
• Base58 — direcciones de Bitcoin, IDs de fotos de Flickr. Excluye los cuatro caracteres ambiguos (0, O, I, l) y +/ para una transcripción humana más fácil. ~37% de sobrecosto.
• Base62 — acortadores de URL, IDs snowflake de Twitter. Usa solo alfanuméricos (sin caracteres especiales), seguro en URLs sin escape. ~34% de sobrecosto.
• Base85 / Ascii85 / Z85 — PostScript, PDF, frames antiguos de ZeroMQ. ~25% de sobrecosto (más denso que Base64) pero con elecciones de caracteres complicadas que pueden causar un infierno de escape XML/JSON.
Estos son interesantes, pero no están estandarizados por RFC 4648. Si estás publicando un protocolo público, Base64 o Base64URL es casi siempre el valor predeterminado más seguro porque la biblioteca estándar de cada lenguaje ya los soporta. Si eliges Base58, estarás enviando una dependencia a cada consumidor.
// PRUÉBALOS LADO A LADO
• Codificador Base64 — alfabeto estándar con un interruptor URL-safe
• Codificador Base64URL — URL-safe con relleno eliminado
• Codificador Base32 — alfabeto RFC 4648 §6
• Codificador Base16 (hex) — para comparación
• Codificador Base58 — alfabeto amigable para humanos al estilo Bitcoin
Lectura adicional:
• ¿Qué es Base64 y cómo funciona?
• URL-safe vs Base64 estándar — la historia completa
• Base64 para UTF-8 y Unicode