Enviar um arquivo
  1. base64hub
  2. Aprenda Base64
  3. Aumento de tamanho
Referência

Aumento de tamanho do Base64: a fórmula exata

Cada 3 bytes viram 4 caracteres, então o Base64 é um terço maior que a entrada, mais até 2 caracteres de preenchimento e eventuais quebras de linha.

A fórmula

Para uma entrada de n bytes, o Base64 com preenchimento (o padrão da RFC 4648) tem exatamente:

length = 4 × ceil(n / 3)

Sem preenchimento, como no Base64URL dos JWTs, tem:

length = ceil(4n / 3)

As duas diferem pelo número de sinais =, que é 0, 1 ou 2, dependendo de n mod 3. O guia de preenchimento explica de onde eles vêm.

No sentido inverso, uma string Base64 com preenchimento de comprimento L decodifica para:

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

Então TWFu são 3 bytes, TWE= são 2 e TQ== é 1. Remova espaços em branco e quebras de linha antes de contar. A calculadora de tamanho Base64 faz as duas direções, incluindo quebras de linha e prefixos de data URI.

Em 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 que o aumento é de 33%

Um byte tem 8 bits. Um caractere Base64 carrega 6 bits de dados, porque é um entre 64 = 2⁶ símbolos, mas é armazenado como um byte ASCII de 8 bits. Assim, cada byte de saída guarda 6 bits úteis, e a saída precisa ter 8/6 = 4/3 da entrada. São 33,3% a mais, e esse é um piso rígido: nenhuma implementação de Base64 faz melhor sem abandonar o alfabeto. (Como os bits são reagrupados é mostrado passo a passo em como o Base64 funciona.)

Em entradas pequenas, o preenchimento piora a proporção, já que a saída sempre vem em blocos de 4. Um byte vira 4 caracteres, um aumento de 300%. A partir de algumas centenas de bytes, o preenchimento fica desprezível e a proporção se estabiliza em 4/3.

Existem codificações de texto mais densas. O Base85 guarda 4 bytes em 5 caracteres (25% de aumento), e o Base91 fica um pouco abaixo disso. Elas têm suporte menos amplo, e os alfabetos delas incluem caracteres que causam problemas em alguns contextos. A comparação está em Base64 vs hex, Base32, Base58, Base85.

Quebras de linha: MIME, PEM e ferramentas de linha de comando

Alguns formatos quebram o Base64 em linhas, e os finais de linha entram na conta do tamanho.

FormatoComprimento da linhaFinal de linhaAumento total
Base64 simples (RFC 4648)sem quebranenhum33,3%
E-mail MIME (RFC 2045)76CRLF (2 bytes)36,8%
base64 do GNU, encodebytes do Python76LF (1 byte)35,1%
Certificados e chaves PEM64LF35,4%

O número do MIME vem de 4/3 × 78/76: cada 76 caracteres de Base64 trazem mais 2 bytes de CRLF. Com L = 4 × ceil(n / 3), o tamanho incluindo um CRLF depois de cada linha, inclusive a última, é:

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

Cada linha completa de 76 caracteres guarda exatamente 57 bytes de entrada, e é por isso que os codificadores MIME processam os dados em blocos de 57 bytes. Mais sobre e-mail em Base64 em e-mail, e o codificador Base64 MIME gera saída quebrada em linhas.

Tabela de tamanhos

Calculada com as fórmulas acima e conferida com o módulo base64 do Python.

EntradaBase64 com preenchimentoSem preenchimentoMIME (76 + CRLF)Aumento (com preenchimento)
1 byte426300%
2 bytes436100%
3 bytes44633,3%
10 bytes16141860%
57 bytes76767833,3%
100 bytes13613414036%
1.000 bytes1.3361.3341.37233,6%
1 KiB (1.024)1.3681.3661.40433,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%

A última linha é o caso do e-mail. Os limites de tamanho do SMTP (a extensão SIZE, RFC 1870) contam a mensagem como ela é transmitida, com a codificação, então um arquivo de 25 MB vira cerca de 34,2 MB na transmissão e não passa por um servidor com limite de 25 MB. Alguns provedores descrevem os limites em termos do anexo, então confira como o seu faz a conta.

O que a compressão faz

A compressão interage com o Base64 de duas formas, e a ordem importa.

Compacte antes de codificar sempre que você controlar as duas pontas. O Base64 de dados compactados é 4/3 de um número menor. Para o texto da licença GPL-3 (35.149 bytes), medimos com o zlib do Node.js no nível 9 do gzip:

PipelineTamanho
Texto bruto35.149
Só Base6446.868
Base64, depois gzip17.465
gzip, depois Base6416.124
Só gzip12.091

A ferramenta Gzip + Base64 faz o pipeline “gzip, depois Base64” no navegador.

A compressão no transporte recupera a maior parte do aumento em dados binários. Se uma string Base64 viaja dentro de uma resposta HTTP compactada com gzip ou Brotli, o compressor espreme os caracteres de 6 bits de volta para perto de 6 bits cada. Para 1 MiB de bytes aleatórios, o Base64 cresceu para 1.398.104 caracteres; com gzip ficou em 1.053.023 bytes (0,4% acima dos dados brutos), e o Brotli chegou a 1.048.805. Os mesmos dados com quebras de linha MIME ficaram em 1.088.689 com gzip, então os CRLFs custam cerca de 3,4% mesmo depois da compressão.

Com texto é diferente. O Base64 quebra a repetição de que os compressores dependem, então texto em Base64 compacta bem pior que o próprio texto: 17.465 contra 12.091 bytes na tabela acima. O artigo sobre desempenho de data URIs traz medições para PNG, JPEG, WOFF2 e SVG.

O Base64 incha tudo o que você coloca numa URL, num header ou num cookie, e os três têm limites.

  • URLs. A RFC 9110 recomenda que remetentes e destinatários suportem URIs de pelo menos 8.000 octetos. Muitos servidores param perto disso por padrão: o nginx aloca buffers de header de 8 KB para a linha de requisição, e o LimitRequestLine do Apache tem padrão de 8.190 bytes. URLs mais longas costumam falhar com 414 URI Too Long. Com Base64URL, isso dá espaço para uns 6.000 bytes de dados, descontado o resto da URL.
  • Headers. Os mesmos buffers do servidor valem para cada linha de header, o que importa para JWTs longos em headers Authorization: Bearer ... e para credenciais Basic Auth grandes.
  • Cookies. A RFC 6265 pede que os navegadores suportem pelo menos 4.096 bytes por cookie, incluindo o nome e os atributos. Isso dá cerca de 3 KB de dados depois de codificados em Base64.

Se um payload Base64 está chegando perto de algum desses limites, envie-o no corpo da requisição ou guarde-o no servidor e passe um ID.

Calcular o tamanho do Base64

Informe uma quantidade de bytes ou cole uma string para ver os tamanhos codificado e decodificado, com ou sem quebras de linha.

Calculadora de tamanho

Perguntas frequentes

Quanto o Base64 é maior que o arquivo original?

Cerca de 33,3% para qualquer coisa com mais de alguns bytes. Com quebras de linha MIME (76 caracteres mais CRLF), são cerca de 36,8%.

Como calcular o tamanho original a partir de uma string Base64?

Pegue o comprimento sem espaços em branco, multiplique por 3/4 e subtraia o número de sinais = no final. Por exemplo, TWE= dá 4 × 3/4 − 1 = 2 bytes.

Por que uma entrada de 1 byte gera 4 caracteres?

Com preenchimento, o Base64 sempre gera blocos completos de 4 caracteres. Um byte ocupa 2 caracteres e os outros 2 são =, então entradas minúsculas têm um aumento relativo bem maior.

Dá para deixar o Base64 menor?

Compacte os dados antes de codificar, por exemplo com gzip, e dispense o preenchimento se o destinatário permitir. O Base64 em si tem uma proporção fixa; existem codificações de texto mais densas, como o Base85, mas com suporte menos amplo.

Continue lendo