Base64 es una forma de escribir bytes arbitrarios — una imagen, una clave, un archivo zip — usando solo 64 caracteres de texto plano, para que los datos sobrevivan a canales que se construyeron para texto y estropean cualquier otra cosa. Funciona por bloques: entran tres bytes, salen cuatro caracteres, lo que deja el resultado alrededor de un tercio más grande que lo que tenías al empezar. Es una codificación, no un cifrado. Cualquiera que vea el string lo puede revertir en un segundo, sin clave y sin contraseña.
¿Cómo funciona Base64 en realidad?
Tres bytes son 24 bits. Base64 corta esos 24 bits en cuatro grupos de seis. Seis bits guardan un número del 0 al 63, y cada número se corresponde con un carácter de un alfabeto fijo: A–Z para 0–25, a–z para 26–51, los dígitos 0–9 para 52–61, y después + y /. Veintiséis más veintiséis más diez más dos son sesenta y cuatro, y de ahí sale el nombre.
Toma la palabra Man. Esos tres bytes son 01001101 01100001 01101110. Reagrupados de seis en seis se leen 010011, 010110, 000101, 101110 — es decir, 19, 22, 5 y 46. Busca cada número en el alfabeto y obtienes TWFu. Sin compresión, sin clave. Los mismos bits, cortados de otra manera.
¿Por qué tantos strings Base64 terminan en signos =?
La entrada casi nunca es un múltiplo exacto de tres bytes. Cuando no lo es, el codificador rellena el último grupo con bits en cero y anota lo que faltó con caracteres =. Un = significa que el último grupo tenía dos bytes; dos de ellos significan que tenía uno. La letra suelta M se codifica como TQ==. Nunca vas a ver tres caracteres de relleno, porque tres bytes que faltan no forman un grupo parcial en absoluto.
Esa es también la comprobación más rápida sobre un string que alguien te pasó. Para ver qué hay de verdad dentro de uno, el codificador y decodificador Base64 de aquí quita los espacios en blanco, devuelve el relleno que falta y rechaza una longitud que no puede ser correcta en lugar de entregar un sinsentido en silencio. Acepta texto que pegas, no archivos — no hay selector de archivos, y un archivo binario tirado dentro de una caja de texto ya está arruinado — y corre en la pestaña, así que un token que estás depurando nunca sale de tu computadora.
¿Por qué existe Base64 en primer lugar?
Porque buena parte de la infraestructura se diseñó para texto y se rompe con bytes crudos. El correo electrónico es el caso original: SMTP se especificó para ASCII de 7 bits, así que un archivo lleno de bytes arbitrarios de 8 bits no se podía meter sin más en un mensaje. MIME, el estándar que permite que el correo transporte algo que no sea texto plano, definió Base64 como una de sus codificaciones de transferencia a principios de los años noventa, y así es como sigue viajando cada adjunto que mandas.
El mismo problema vuelve una y otra vez con ropa nueva. JSON no tiene ningún tipo binario — un string tiene que ser texto válido, y un byte de control crudo en medio de uno no lo es. Un archivo de configuración YAML, un documento XML, una columna de texto de una base de datos, una línea de log: todos aceptan los 64 caracteres de Base64 sin discutir, y todos hacen algo impredecible con el byte 0x00. Base64 es la respuesta aburrida y universal. Haz que los bytes parezcan texto y el canal de texto deja de preocuparse por lo que son.
¿Dónde te encuentras con Base64?
- Adjuntos de correo. Cortados a 76 caracteres por línea, porque SMTP nunca prometió que algo más largo fuera a llegar intacto.
- Data URIs.
data:image/png;base64,…mete un archivo entero dentro de un archivo HTML o CSS. Útil para un ícono diminuto, caro para cualquier otra cosa — cuándo conviene de verdad incrustar una imagen es una pregunta más estrecha de lo que parece. - JSON Web Tokens. El header y el payload son base64url, y por eso puedes leer un JWT sin ninguna clave.
- Autenticación HTTP Basic. El header
AuthorizationllevaBasicseguido del Base64 deusuario:contraseña. Eso es ofuscación, no protección, y es la razón por la que Basic auth sin HTTPS equivale a mandar la contraseña en claro. - Archivos PEM. Los certificados y las claves privadas son Base64 cortado a 64 caracteres entre las líneas BEGIN y END.
- Valores opacos de API. Cursores de paginación, IDs de subida, cookies firmadas. Decodificar uno suele revelar un timestamp y un ID de registro que alguien supuso que nadie iba a mirar.
¿Qué es base64url y por qué lo usan los tokens?
El RFC 4648 define dos alfabetos, y el segundo existe porque el primero es hostil dentro de una URL. Un + en un query string lo leen como espacio los decodificadores de formularios, un / termina un segmento de ruta, y el relleno = hay que escaparlo. base64url conserva los primeros 62 caracteres, cambia los dos últimos por - y _, y normalmente deja fuera el relleno.
Los bits de abajo son idénticos, y eso es justo lo que vuelve caro el desajuste. Dos strings se diferencian solo donde cayó un + o un /, así que a simple vista se ven iguales, y un token que decodifica limpio en una biblioteca y sale hecho basura en otra suele haber cruzado esa frontera. Es también la razón por la que un string del alfabeto estándar pegado en un parámetro de query vuelve con espacios donde estaban sus signos + — apenas un rincón del lío más grande, ese que el URL encoding existe para limpiar.
Por qué Base64 no es cifrado, ni compresión
No hay clave, no hay secreto y no hay trabajo alguno en revertirlo. Una contraseña guardada en Base64 dentro de un archivo de configuración es una contraseña en texto plano con un disfraz puesto: detiene una mirada casual y nada más.
Los JWT confunden a la gente por el mismo motivo. Los claims de un token están firmados, no ocultos: la firma demuestra que el payload no fue alterado, y no demuestra nada sobre quién lo tiene. Cualquiera que tenga el token, incluido el usuario cuyo navegador lo está guardando, puede leer todos los campos. Pega uno en un decodificador de JWT y salen directo los IDs internos de usuario, las direcciones de correo y los flags de rol. Qué contiene realmente un JWT cubre el resto, incluidas las partes que sí están genuinamente protegidas.
Tampoco es compresión. Codificar un archivo zip en Base64 lo hace un tercio más grande, no más chico. Comprime primero y codifica después, nunca al revés: Base64 desplaza las secuencias repetidas fuera del alineamiento de bytes, porque los mismos tres bytes se codifican como caracteres distintos según en qué punto del flujo empiecen. Un compresor pasado sobre el texto codificado encuentra mucho menos con lo que trabajar que uno pasado sobre los bytes originales.
¿Cuánto cuesta en realidad ese 33% de más?
Cuatro caracteres por cada tres bytes es un costo fijo, y los saltos de línea suman un poco más encima. Un adjunto de 5 MB viaja como unos 6,7 MB de Base64. Un logo de 40 KB incrustado como data URI le agrega unos 53 KB al archivo HTML, y a diferencia de una imagen aparte no se puede cachear por su cuenta ni pedir en paralelo.
Gzip recupera algo de eso, ya que la salida solo usa 64 caracteres distintos, pero no te deja en el tamaño de los bytes crudos. Si un transporte puede llevar binario, lleva binario. Base64 se gana su costo solo cuando el canal genuinamente no puede.
¿Qué se rompe normalmente?
Caracteres acentuados y emoji. El btoa() del navegador no acepta texto. Acepta una binary string, donde cada carácter tiene que caber en un solo byte, y cualquier cosa por encima de U+00FF lanza InvalidCharacterError. El inglés simple pasa todas las pruebas que escribas, y el primer cliente que se llame Zoë rompe producción. Convierte el texto a bytes UTF-8 y codifica esos — TextEncoder lo hace en el navegador, y Python y Node lo hacen por defecto.
Relleno que falta. Muchos decodificadores, incluido el de este sitio, te lo restauran. Muchas bibliotecas estrictas se niegan. Si un token base64url decodifica en una página web y falla en tu código, esto es lo primero que hay que revisar.
Saltos de línea. Se supone que los decodificadores los ignoran y la mayoría lo hace, pero algunos parsers embebidos y empresariales viejos no. Un bloque copiado de un correo es la fuente habitual.
Doble codificación. Codificar un string ya codificado es válido, silencioso, y hace crecer los datos otro tercio. Te enteras cuando el resultado decodificado es a su vez Base64.
Esperar texto a la salida. Si los bytes originales eran una imagen, la salida decodificada es ruido, y un decodificador permisivo te muestra mojibake en vez de un error. No hay nada roto; el payload nunca fue texto.
¿Cuándo conviene usar otra cosa?
Base64 responde una sola pregunta: cómo muevo bytes a través de un canal que solo acepta texto. Si necesitas ocultar algo, usa cifrado; si necesitas achicarlo, comprímelo. Y si el problema real es que unos pocos caracteres tienen significado estructural dentro del documento que los rodea, un escape más estrecho le gana a codificarlo todo — entidades HTML para markup, percent-encoding para URLs, comillas estándar para CSV. Esos mantienen el contenido legible, que es justo lo que Base64 destruye por diseño.
La forma más rápida de volver concreto todo esto es pasar un string por ahí. El codificador y decodificador Base64 lee los dos alfabetos, restaura el relleno que falta, cuenta los bytes que entran contra los caracteres que salen, y maneja bien UTF-8, así que el texto acentuado que rompe btoa() sobrevive intacto a la ida y la vuelta. Funciona sobre texto pegado y no sobre archivos, lo que cubre tokens, claves y valores de configuración, pero no un PDF.
Si llegaste aquí porque un string en un archivo de configuración o en una URL no hacía lo que esperabas, el problema vecino suele ser el escapado y no la codificación. Entidades HTML: cuándo las necesitas y cuándo no cubre la otra mitad de eso — qué caracteres hay que escapar, cuáles escapa la gente por superstición, y qué te cuesta la diferencia.
Preguntas frecuentes
¿Para qué se usa Base64?
Se usa para mover datos binarios por canales que solo aceptan texto: adjuntos de correo, data URIs dentro de HTML y CSS, JSON Web Tokens, archivos de certificado PEM y headers de autenticación HTTP Basic. En todos los casos la idea es que el sistema que recibe corrompería o rechazaría los bytes crudos. Base64 reescribe esos bytes usando 64 caracteres que cualquier canal de texto transporta sin cambiarlos.
¿Base64 es cifrado?
No. Base64 no tiene clave ni secreto, y cualquiera que vea el string lo puede decodificar al instante con una herramienta gratuita o una línea de código. Es una codificación, pensada para el transporte, no para la privacidad. Una contraseña guardada en Base64 es una contraseña en texto plano con un paso extra.
¿Por qué Base64 agranda los archivos?
Porque convierte cada tres bytes en cuatro caracteres, lo que es un aumento fijo del 33%, y el corte de líneas suma un poco más. Un archivo de 5 MB se convierte en unos 6,7 MB de Base64. Por eso conviene comprimir un archivo antes de codificarlo, nunca después.
¿Qué significan los signos = al final de un string Base64?
Son relleno, agregado cuando la longitud de la entrada no era múltiplo de tres bytes. Un = significa que el grupo final tenía dos bytes, y dos = significan que tenía uno. Un string válido nunca termina en tres caracteres de relleno. Algunas variantes, incluido el base64url que usan los JWT, eliminan el relleno por completo.
¿Cómo sé si un string es Base64?
No puedes estar seguro, solo descartarlo. Base64 usa A–Z, a–z, 0–9 y dos caracteres más, y su longitud con relleno es múltiplo de cuatro, así que cualquier cosa fuera de ese conjunto no es Base64. Pero las palabras comunes también pasan la prueba: "test" es un string Base64 válido que decodifica a tres bytes de basura binaria. Decodificarla y mirar el resultado es la única comprobación real.
¿Por qué btoa() falla con caracteres acentuados?
btoa() espera una binary string, donde cada carácter es un solo byte, así que cualquier cosa por encima de U+00FF lanza InvalidCharacterError. Los acentos y los emoji están por encima de ese límite. Convierte el texto a bytes UTF-8 con TextEncoder primero, codifica esos bytes, y el resultado va a coincidir con lo que producen Python y Node.
Última actualización 19 de septiembre de 2026