O último caractere contém bits sem dados
RFC 4648 §3.5 exige que codificadores conformes zerem os bits de preenchimento. Com um byte de entrada, apenas os dois bits superiores do segundo caractere Base64 são dados; os outros quatro são preenchimento. g tem índice 32, 100000; h tem índice 33, 100001. O byte de f é 01100110 e os bits de dados coincidem. Zg== é a saída canônica; Zh== contém bits de preenchimento não nulos. Não confunda os caracteres = finais com os bits descartados.
Confira a decodificação e a recodificação
A decodificação tolerante do WHATWG Infra descarta quatro bits finais de um grupo restante de 12 bits, ou dois de um grupo de 18. HTML atob usa esse algoritmo. Moyoutil recupera bytes com atob e interpreta texto UTF-8. Nos exemplos executados, Zg== e Zh== retornaram f; Zm8= e Zm9= retornaram fo. Recodificar produziu Zg== e Zm8=. O código abaixo recodifica bytes diretamente, sem transformar binários arbitrários em texto UTF-8.
for (const input of ['Zg==', 'Zh==', 'Zm8=', 'Zm9=']) {
const bytes = atob(input);
const canonical = btoa(bytes);
console.log(input, bytes, canonical, input === canonical);
}
// Zg== f Zg== true
// Zh== f Zg== false
// Zm8= fo Zm8= true
// Zm9= fo Zm8= falseBytes iguais e strings originais iguais são condições diferentes. Defina a igualdade necessária para a chave de cache ou comparação. Se o protocolo receptor exigir entrada canônica, valide suas regras. Não recomendamos alterar strings assinadas antes da verificação. Esta comparação cobre apenas Base64 padrão com preenchimento; não é um validador de todos os protocolos.
Perguntas frequentes
Todo decodificador aceita Zh==?
Não. RFC 4648 permite rejeitar bits de preenchimento não nulos, e uma especificação que o referencia pode definir o comportamento. Os resultados descrevem HTML atob e a implementação atual do Moyoutil.