Ferramentas de desenvolvedor · Codificador e decodificador Base64
RFC 4648 explicado: o padrão que define Base64, base32 e base16
· Fundo
base64 codificação
RFC 4648 é o documento curto e legível por trás de cada implementação Base64. Esta postagem aborda o que especifica, o que deixa deliberadamente em aberto e por que as implementações ainda diferem.
Duas bibliotecas, duas respostas para a mesma string — um verdadeiro quebra-cabeça de interoperabilidade que somente o padrão resolve
Duas bibliotecas JavaScript podem retornar Base64 diferentes para a mesma string, cada uma alegando correção. RFC 4648 é o documento legível de doze páginas que deve resolver tais divergências, mas as implementações ainda diferem porque o RFC deixa deliberadamente certas decisões para os aplicativos. Este artigo explica o que RFC 4648 especifica, o que ele delega intencionalmente aos chamadores e por que a leitura do padrão uma vez resolve a maioria dos quebra-cabeças reais de interoperabilidade. A ferramenta codificadora e decodificadora Base64 inclui vetores de teste RFC 4648 para que você possa verificar uma implementação em relação aos exemplos oficiais.
RFC 4648 substituiu e consolidou vários documentos anteriores: Base64 de MIME (RFC 2045), Base64 de Privacy-Enhanced Mail (RFC 1421), base32 de S/MIME (RFC 2630) e base16 de várias fontes. A consolidação foi necessária porque MIME e PEM cada um tinha seu próprio alfabeto e regras, e a quebra de linha de MIME entrava em conflito com os blocos de coluna 64 de PEM. RFC 4648 define cinco famílias de codificação em um só lugar: base64, base64url, base32, base32hex e base16, cada uma com seu próprio alfabeto, regras de preenchimento e exemplos de vetores de teste. O alfabeto base64 é A-Z, a-z, 0-9, mais e barra, nesta ordem.
O que os vetores de implementação e teste estabelecem — alfabetos padrão e URL-safe, preenchimento e manipulação de espaços em branco
Cada caractere representa 6 bits; três bytes de entrada (24 bits) são mapeados para quatro caracteres de saída. O alfabeto não é arbitrário: ele evita caracteres que diferem entre EBCDIC e ASCII, evitando caracteres de controle, aspas e a barra invertida que precisaria escapar em literais de string C. A variante base64url substitui o sinal de mais por traço e barra por sublinhado para evitar caracteres reservados em URLs e nomes de arquivos. Ambas as variantes são igualmente válidas; RFC 4648 seção 2 especifica base64, seção 5 especifica base64url e um aplicativo deve indicar qual deles ele usa.
O preenchimento com caracteres iguais traz a saída para um múltiplo de quatro caracteres. Se a entrada for 1 byte (8 bits), a saída terá dois caracteres mais dois sinais de igual. Se a entrada for 2 bytes (16 bits), a saída terá três caracteres mais um sinal de igual. Se a entrada for um múltiplo de 3 bytes, nenhum preenchimento será necessário. Alguns aplicativos omitem o preenchimento ou permitem a falta de preenchimento na decodificação; A seção RFC 4648 3.2 define a codificação canônica como sempre preenchida, mas a seção 3.3 observa que os decodificadores podem aceitar preenchimento ausente para compatibilidade.
Os alfabetos que esta ferramenta implementa — Base64 e Base64url padrão; outras bases permanecem fora do seu âmbito
A distinção de preenchimento é a razão pela qual as implementações discordam: um decodificador estrito rejeita iguais ausentes, enquanto um decodificador tolerante o aceita. RFC 4648 diz explicitamente: o caractere de preenchimento igual é normalmente codificado por porcentagem quando usado em URLs, portanto, se a saída base64url for usada diretamente em um parâmetro URL, o preenchimento não será necessário e deverá ser omitido. Esta frase é um dos motivos pelos quais o modo de segurança URL e a omissão de preenchimento costumam ser combinados, embora sejam escolhas independentes. A seção 5 (base64url) não proíbe preenchimento; apenas observa a prática comum.
Um chamador que escolhe base64url deve decidir se o preenchimento é necessário para o sistema receptor. Caracteres não alfabéticos na entrada são tratados de maneira diferente por decodificadores diferentes. A seção RFC 4648 3.1 declara: Implementações MUST rejeitam a codificação se ela contiver caracteres fora do alfabeto base. No entanto, a seção 3.3 observa que MIME Base64 (RFC 2045) permite quebras de linha para quebra de caracteres 76 e decodificadores para MIME devem pular os espaços em branco. O RFC distingue entre decodificação estrita (rejeitar todos os que não sejam do alfabeto) e decodificação compatível com MIME (ignorar espaços em branco, rejeitar outros caracteres).
Preenchimento, caracteres não alfabéticos e codificação canônica — as seções que explicam a maioria das divergências entre decodificadores
Um aplicativo deve escolher qual regra seguir; o padrão define ambos. Base32 usa A-Z e 2-7 (32 caracteres no total), codificando cinco bytes de entrada (40 bits) para oito caracteres de saída. Base32hex substitui 0-9 e a-v para os caracteres alfabéticos, útil em contextos onde letras minúsculas são preferidas.
Base16 é hexadecimal: 0-9 e a-f. Base32 e base32hex têm suas próprias regras de preenchimento nas seções 6 e 7, e RFC fornece vetores de teste separados para cada alfabeto. A maioria dos desenvolvedores precisa apenas de base64 e base64url; base32, base32hex e base16 estão incluídos no RFC para integridade e para aplicativos como segredos TOTP (RFC 4226) e codificação DNS.
Opções de aplicação visíveis nesta implementação — quebra de linha, decodificação estrita de texto e tratamento de erros
Os vetores de teste em RFC 4648 são a base para verificar uma implementação. A codificação das strings f, fo, foo, foob, fooba e foobar produz uma saída base64 específica: Zg==, Zm8=, Zm9v, Zm9vYg==, Zm9vYmE= e Zm9vYmFy. Uma implementação que produz resultados diferentes para essas cadeias de caracteres está incorreta. O RFC fornece vetores de teste equivalentes para base32, base32hex e base16. A ferramenta codificador e decodificador Base64 inclui esses vetores para que você possa verificar sua saída em relação ao padrão. A quebra de linha é uma preocupação MIME, não uma preocupação base64.
RFC 2045 especifica linhas de 76 caracteres; A seção RFC 4648 3.1 observa isso no contexto de MIME, mas não o torna um requisito da própria base64. Alguns aplicativos são agrupados em 64 caracteres (o padrão PEM original); outros nem embrulham. Um decodificador base64 estrito RFC 4648 opera apenas no alfabeto e no preenchimento. Um decodificador compatível com MIME deve pular quebras de linha (CR, LF, CRLF). Um aplicativo que usa base64 fora de MIME não deve adicionar quebras de linha, a menos que o sistema receptor as exija; o RFC não define quebra de linha como parte do base64.
Exemplo resolvido: os próprios vetores de teste do RFC — codificando os prefixos 'foobar' e verificando-os no navegador
O tratamento de espaços em branco é outro ponto de variação de implementação. RFC 4648 diz que decodificadores estritos devem rejeitar caracteres não alfabéticos. Base64 encapsulado em MIME (RFC 2045 base64) permite espaços em branco para formatação. Os dois padrões concordam sobre quais devem ser os bytes de saída, mas diferem sobre qual entrada é válida. A maioria das implementações de JavaScript escolhe a compatibilidade de MIME e ignora os espaços em branco; a regra estrita raramente é usada em navegadores. O codificador e decodificador Base64 aceita entradas contendo espaços em branco (MIME) e restritas, tornando a distinção explícita. A decodificação canônica versus a decodificação indulgente é a principal variação final.
A decodificação canônica segue a seção RFC 4648 3.2: rejeitar preenchimento malformado, rejeitar preenchimento ausente, rejeitar caracteres não alfabéticos. A decodificação indulgente, usada em padrões da web (a especificação HTML a chama de perdão-base64), adiciona regras: ignorar espaços em branco, aceitar preenchimento ausente, permitir traço e sublinhado como equivalentes de mais barra, mesmo no modo base64 padrão. O atob() de JavaScript é indulgente; um decodificador RFC 4648 estrito é mais estrito. Nenhum dos dois está errado; eles atendem a contextos diferentes. Uma aplicação que lê dados de um usuário ou da rede deve saber qual regra o outro lado espera.
O que isso não cobre — os próprios documentos MIME e PEM e APIs específicas da linguagem
O RFC deixa nove opções para o aplicativo: qual dos cinco alfabetos, exigir ou permitir preenchimento, exigir ou permitir espaços em branco, tratar o sublinhado de traço como equivalente de mais barra, como relatar erros, como lidar com o final da entrada, se deve aceitar preenchimento ausente, quantos bytes de saída alocar e como sinalizar um limite de tamanho. Essas escolhas explicam por que duas implementações de RFC 4648 podem discordar na mesma entrada. Leia o RFC uma vez; verifique sua implementação em relação aos vetores de teste; indique quais opções seu aplicativo usa; testar a interoperabilidade com o par real, não com suposições.
Compreender RFC 4648 resolve a maioria das disputas Base64 porque a discordância geralmente não é sobre o RFC em si, mas sobre quais opções cada lado escolheu. O RFC é breve o suficiente para ser lido de ponta a ponta em uma hora. O padrão define os alfabetos, fornece vetores de teste e avisa onde as implementações devem decidir. A ferramenta codificador e decodificador Base64 permite experimentar os vetores de teste e ver o alfabeto padrão em ação. A maior parte do uso diário de base64 não requer conhecimento profundo de RFC; mas ao depurar incompatibilidades de codificação ou integrar com um API desconhecido, ler o padrão uma vez elimina suposições.
Conclusão: leia o padrão uma vez - como o codificador e decodificador Base64 oferece uma maneira rápida de verificar os vetores de teste do alfabeto padrão
RFC 4648 é a consolidação de décadas de prática de codificação básica ad-hoc em uma especificação legível. Ele não define quando usar base64 (MIME, PEM, JWT, URIs de dados, etc. cada um tem suas próprias especificações); ele define o que é base64. Ao definir cinco famílias de codificação e observar quais opções são canônicas, o RFC permite verificar se uma implementação está correta. Os vetores de teste autorizados são o ponto de partida: se sua implementação codifica foobar e produz algo diferente de Zm9vYmFy, o RFC diz que a implementação está errada.
Use essa autoridade como um ponto de verificação: codifique cada vetor de teste RFC, compare os caracteres exatos e, em seguida, decodifique o resultado para confirmar se os bytes originais retornam inalterados. Essa verificação baseada no navegador separa um erro de alfabeto ou preenchimento de um problema em outra parte da integração, mantendo o próprio padrão como referência, em vez de depender de um rótulo de biblioteca.