Base64 explicado: agrupamento de 6 bits, ~33% de inflação de tamanho, preenchimento e base64url vs padrão

O que é Base64 — e o que não é

Base64 é um esquema de codificação de binário para texto. Converte dados binários arbitrários em uma string de caracteres ASCII imprimíveis, tornando esses dados seguros para incorporar em contextos projetados para texto legível por humanos. Base64 não é compressão — torna os dados maiores. Também não é criptografia — qualquer um que tenha a string codificada pode recuperar os bytes originais trivialmente. O nome vem do fato de que usa um alfabeto de exatamente 64 caracteres, escolhido porque 2⁶ = 64 permite que cada caractere represente exatamente 6 bits de entrada.

Base64 não foi inventado como um padrão independente; surgiu da necessidade de enviar anexos de e-mail binários através de infraestrutura SMTP que só transmitia de forma confiável ASCII de 7 bits. RFC 2045 (1996), que define MIME, padronizou a codificação para e-mail. Uma década depois, RFC 4648 (2006) consolidou base64 e suas variantes — incluindo base32 e base64url — em um único documento de referência. RFC 4648 ainda é a especificação autoritativa usada hoje por qualquer novo protocolo que precise de uma codificação binário para texto.

O agrupamento de 6 bits: como três bytes de entrada se tornam quatro caracteres

O núcleo do base64 é uma operação simples de reempacotamento de bits. Dados binários chegam em grupos de bytes de 8 bits; base64 reagrupa esses bits em pedaços de 6 bits, cada um mapeando para um caractere no alfabeto de 64 caracteres. Como o mínimo múltiplo comum de 6 e 8 é 24, a unidade de processamento natural é 3 bytes = 24 bits → 4 caracteres. Tomando Man como exemplo concreto: os três bytes são 0x4D, 0x61, 0x6E, dando a sequência de bits 01001101 01100001 01101110. Reagrupados em quatro valores de 6 bits: 010011 (19 → T), 010110 (22 → W), 000101 (5 → F), 101110 (46 → u). O resultado codificado é TWFu.

Esta relação de 3 para 4 bytes é a fonte direta da inflação de tamanho. Para cada 3 bytes de entrada, a saída é sempre 4 caracteres independentemente dos valores reais dos bytes. Para n bytes de entrada, a saída codificada é ceil(n / 3) × 4 caracteres, o que significa que a saída é sempre 33% maior que a entrada (exatamente 4/3 vezes maior). Um arquivo de 1 KB codifica para aproximadamente 1,37 KB; uma imagem de 1 MB codifica para aproximadamente 1,37 MB.

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

O alfabeto base64 padrão mapeia valores de 6 bits 0–63 para caracteres ASCII imprimíveis nesta ordem: valores 0–25 mapeiam para AZ maiúsculas, valores 26–51 para az minúsculas, valores 52–61 para dígitos 09, valor 62 para +, e valor 63 para /. Este ordenamento coloca letras antes de dígitos por razões históricas de compatibilidade MIME. A escolha de + e / para os dois últimos valores causou décadas de problemas de interoperabilidade, pois ambos os caracteres têm significado especial em URLs.

Um equívoco comum é que base64 é independente do conjunto de caracteres. Não é: o alfabeto é ASCII fixo. Um decodificador que encontrar um caractere fora do conjunto de 65 caracteres (64 caracteres de dados mais = para preenchimento) deve rejeitar a entrada ou ignorá-la dependendo do contexto da especificação. RFC 4648 recomenda rejeitar caracteres fora do alfabeto no modo estrito. O sinal de igual = é um marcador, não um caractere de dados — ele marca o preenchimento e nunca deve aparecer exceto no final de uma string codificada.

Preenchimento: por que os sinais de igual existem e quando podem ser omitidos

Como a codificação processa 3 bytes por vez, entradas cujo comprimento não é divisível por 3 deixam um grupo parcial no final. O preenchimento resolve isso: força a saída codificada a ser sempre um múltiplo de 4 caracteres, tornando possível calcular a contagem de bytes original apenas a partir do comprimento de saída. Se a entrada tem 1 byte restante, 2 caracteres de preenchimento == são anexados. Se a entrada tem 2 bytes restantes, 1 caractere de preenchimento = é anexado.

O preenchimento é opcional em contextos onde o comprimento total é conhecido por outros meios. RFC 7515, a especificação JSON Web Signature, requer explicitamente que as implementações omitam o preenchimento = ao codificar componentes JWT, pois os pontos entre as três partes de um JWT já delimitam os segmentos. Portanto, valores codificados em base64url em JWTs nunca terminam em =. Restaurar o preenchimento é simples: adicionar caracteres = até que o comprimento da string seja múltiplo de 4.

Base64url: a variante URL-segura usada em JWTs e tokens OAuth

Os caracteres + e / do base64 padrão são problemáticos em contextos URL. Um + em uma query string é interpretado como espaço sob a codificação application/x-www-form-urlencoded. Um / é um separador de segmento de caminho. Base64url, definido na Seção 5 do RFC 4648, substitui + por - e / por _. Esses dois caracteres são seguros em URLs sem codificação percentual. O preenchimento = também é tipicamente omitido em contextos base64url.

Base64url é usado onde quer que uma representação binária compacta e URL-segura seja necessária: as seções de cabeçalho e payload de um JWT são JSON codificado em base64url; códigos de autorização OAuth 2.0 são frequentemente bytes aleatórios codificados em base64url; verificadores e desafios de código PKCE (RFC 7636) usam base64url. A taxa de inflação de dados é idêntica ao base64 padrão — exatamente 4/3 — pois apenas o alfabeto difere, não o algoritmo de agrupamento de bits.

Impacto prático no tamanho e como escolher entre base64 e binário

A sobrecarga de ~33% é o principal custo prático do base64. Para URIs de dados — incorporar imagens, fontes ou SVGs diretamente em HTML ou CSS com data:image/png;base64,... — a troca é eliminar uma viagem de ida e volta HTTP ao custo de um documento maior. Isso é benéfico para recursos pequenos (tipicamente abaixo de 4–8 KB): a viagem de ida e volta economizada supera o aumento de tamanho. Para recursos maiores, o aumento de tamanho degrada o desempenho porque o documento HTML maior demora mais para analisar e não pode ser armazenado em cache separadamente.

A autenticação HTTP básica codifica credenciais como base64(usuario:senha) no cabeçalho Authorization: Basic .... Isso não é uma medida de segurança — o nome de usuário e a senha são trivialmente recuperáveis por decodificação. A autenticação básica requer HTTPS para ser segura; a codificação base64 existe apenas porque a especificação de cabeçalhos HTTP requer ASCII imprimível. Se um payload contém informações sensíveis, base64 não é um substituto para criptografia. Use criptografia autenticada (por exemplo, AES-GCM) ou JSON Web Encryption (JWE, RFC 7516) para dados confidenciais.