Subir un archivo
  1. base64hub
  2. Aprende Base64
  3. Aumento de tamaño
Referencia

Aumento de tamaño de Base64: la fórmula exacta

Cada 3 bytes se convierten en 4 caracteres, así que Base64 ocupa un tercio más que la entrada, más hasta 2 caracteres de relleno y los saltos de línea que haya.

La fórmula

Para una entrada de n bytes, el Base64 con relleno (el predeterminado en el RFC 4648) mide exactamente:

length = 4 × ceil(n / 3)

Sin relleno, como en el Base64URL de los JWT, mide:

length = ceil(4n / 3)

La diferencia entre ambas es el número de signos =, que es 0, 1 o 2 según n mod 3. La guía del relleno explica de dónde salen.

En sentido contrario, una cadena Base64 con relleno de longitud L se decodifica en:

bytes = 3 × L / 4 − (number of trailing "=")

Así, TWFu son 3 bytes, TWE= son 2 y TQ== es 1. Quita los espacios en blanco y los saltos de línea antes de contar. La calculadora de tamaño Base64 hace las dos direcciones, incluidos los saltos de línea y los prefijos de data URI.

En código:

import base64, math, os
for n in [1, 2, 3, 100, 1000]:
    data = os.urandom(n)
    assert len(base64.b64encode(data)) == 4 * math.ceil(n / 3)
const b64Len = (n) => 4 * Math.ceil(n / 3);
const rawLen = (s) => (s.length * 3) / 4 - (s.endsWith("==") ? 2 : s.endsWith("=") ? 1 : 0);
b64Len(1000);    // 1336
rawLen("TWE=");  // 2

Por qué el aumento es del 33 %

Un byte tiene 8 bits. Un carácter Base64 lleva 6 bits de datos, porque es uno de 64 = 2⁶ símbolos, pero se guarda como un byte ASCII de 8 bits. Así que cada byte de salida contiene 6 bits útiles, y la salida tiene que medir 8/6 = 4/3 de la entrada. Eso es un 33,3 % más, y es un mínimo absoluto: ninguna implementación de Base64 puede hacerlo mejor sin abandonar el alfabeto. (Cómo se reagrupan los bits se muestra paso a paso en cómo funciona Base64.)

Con entradas pequeñas, el relleno empeora la proporción, porque la salida siempre va en bloques de 4. Un byte se convierte en 4 caracteres, un aumento del 300 %. A partir de unos cientos de bytes, el relleno es despreciable y la proporción se estabiliza en 4/3.

Existen codificaciones de texto más densas. Base85 guarda 4 bytes en 5 caracteres (un 25 % de aumento), y Base91 baja un poco más. Tienen menos soporte y sus alfabetos incluyen caracteres que dan problemas en algunos contextos. La comparación está en Base64 frente a hex, Base32, Base58, Base85.

Saltos de línea: MIME, PEM y herramientas de línea de comandos

Algunos formatos cortan el Base64 en líneas, y los finales de línea cuentan para el tamaño.

FormatoLongitud de líneaFinal de líneaAumento total
Base64 sin más (RFC 4648)sin cortesninguno33,3 %
Correo MIME (RFC 2045)76CRLF (2 bytes)36,8 %
GNU base64, encodebytes de Python76LF (1 byte)35,1 %
Certificados y claves PEM64LF35,4 %

La cifra de MIME sale de 4/3 × 78/76: cada 76 caracteres de Base64 traen 2 bytes más de CRLF. Con L = 4 × ceil(n / 3), el tamaño incluyendo un CRLF tras cada línea, también la última, es:

mime_length = L + 2 × ceil(L / 76)

Cada línea completa de 76 caracteres contiene exactamente 57 bytes de entrada, y por eso los codificadores MIME procesan los datos en bloques de 57 bytes. Más sobre el correo en Base64 en el correo electrónico; el codificador Base64 MIME genera la salida con cortes de línea.

Tabla de tamaños

Calculada con las fórmulas de arriba y comprobada con el módulo base64 de Python.

EntradaBase64 con rellenoSin rellenoMIME (76 + CRLF)Aumento (con relleno)
1 byte426300 %
2 bytes436100 %
3 bytes44633,3 %
10 bytes16141860 %
57 bytes76767833,3 %
100 bytes13613414036 %
1000 bytes13361334137233,6 %
1 KiB (1024)13681366140433,6 %
1 MB (10⁶)1 333 3361 333 3341 368 42433,3 %
1 MiB (1 048 576)1 398 1041 398 1021 434 89833,3 %
10 MiB13 981 01613 981 01414 348 93833,3 %
25 MB (25 × 10⁶)33 333 33633 333 33434 210 53033,3 %

La última fila corresponde al correo. Los límites de tamaño de SMTP (la extensión SIZE, RFC 1870) cuentan el mensaje tal como se transmite, codificación incluida, así que un archivo de 25 MB se convierte en unos 34,2 MB en la transmisión y no pasará el límite de 25 MB de un servidor. Algunos proveedores expresan sus límites en función del adjunto, así que comprueba cómo cuenta el tuyo.

Qué hace la compresión

La compresión interactúa con Base64 de dos maneras, y el orden importa.

Comprime antes de codificar siempre que controles los dos extremos. El Base64 de unos datos comprimidos es 4/3 de un número más pequeño. Con el texto de la licencia GPL-3 (35 149 bytes) medimos con zlib de Node.js a nivel 9 de gzip:

ProcesoTamaño
Texto original35 149
Solo Base6446 868
Base64 y después gzip17 465
gzip y después Base6416 124
Solo gzip12 091

La herramienta Gzip + Base64 hace el proceso «gzip y después Base64» en el navegador.

La compresión en el transporte recupera casi todo el aumento con datos binarios. Si una cadena Base64 viaja dentro de una respuesta HTTP comprimida con gzip o Brotli, el compresor vuelve a acercar los caracteres de 6 bits a 6 bits cada uno. Con 1 MiB de bytes aleatorios, el Base64 creció hasta 1 398 104 caracteres; con gzip quedó en 1 053 023 bytes (un 0,4 % por encima de los datos originales) y Brotli lo dejó en 1 048 805. Los mismos datos con saltos de línea MIME quedaron en 1 088 689 con gzip, así que los CRLF cuestan alrededor de un 3,4 % incluso después de comprimir.

Con el texto es distinto. Base64 rompe las repeticiones de las que dependen los compresores, así que el texto en Base64 se comprime mucho peor que el propio texto: 17 465 frente a 12 091 bytes en la tabla de arriba. El artículo sobre el rendimiento de los data URI tiene mediciones para PNG, JPEG, WOFF2 y SVG.

Límites de URL, cabeceras y cookies

Base64 hincha todo lo que metas en una URL, una cabecera o una cookie, y las tres tienen límites.

  • URL. El RFC 9110 recomienda que emisores y receptores admitan URI de al menos 8000 octetos. Muchos servidores se cortan cerca de esa cifra por defecto: nginx reserva búferes de cabecera de 8 KB para la línea de petición, y LimitRequestLine de Apache vale 8190 bytes por defecto. Las URL más largas suelen fallar con 414 URI Too Long. Con Base64URL eso deja sitio para unos 6000 bytes de datos, menos el resto de la URL.
  • Cabeceras. Los mismos búferes del servidor se aplican a cada línea de cabecera, algo importante con los JWT largos en cabeceras Authorization: Bearer ... y con credenciales Basic Auth grandes.
  • Cookies. El RFC 6265 pide a los navegadores que admitan al menos 4096 bytes por cookie, incluidos el nombre y los atributos. Eso son unos 3 KB de datos una vez codificados en Base64.

Si un payload Base64 se acerca a alguno de estos límites, envíalo en el cuerpo de la petición, o guárdalo en el servidor y pasa un ID.

Calcula el tamaño en Base64

Introduce un número de bytes o pega una cadena para ver los tamaños codificado y decodificado, con o sin saltos de línea.

Calculadora de tamaño

Preguntas frecuentes

¿Cuánto más ocupa Base64 que el archivo original?

Alrededor de un 33,3 % para cualquier cosa de más de unos pocos bytes. Con saltos de línea MIME (76 caracteres más CRLF), alrededor de un 36,8 %.

¿Cómo calculo el tamaño original a partir de una cadena Base64?

Toma la longitud sin espacios en blanco, multiplícala por 3/4 y resta el número de signos = del final. Por ejemplo, TWE= son 4 × 3/4 − 1 = 2 bytes.

¿Por qué una entrada de 1 byte produce 4 caracteres?

Cuando se usa relleno, Base64 siempre genera bloques completos de 4 caracteres. Un byte ocupa 2 caracteres y los otros 2 son =, así que las entradas muy pequeñas tienen un aumento relativo mucho mayor.

¿Puedo hacer que Base64 ocupe menos?

Comprime los datos antes de codificarlos, por ejemplo con gzip, y quita el relleno si el receptor lo permite. Base64 en sí tiene una proporción fija; existen codificaciones de texto más densas, como Base85, pero tienen menos soporte.

Sigue leyendo