Ferramentas de desenvolvedor · Codificador e decodificador Base64
Decodificando Base64 para UTF-8 sem mojibake: atob mais TextDecoder
· Como funciona
base64 codificação Unicode
atob() retorna bytes disfarçados de caracteres, e é por isso que o texto acentuado parece quebrado após a decodificação. Esta postagem mostra o pipeline correto de Base64 para bytes até o texto UTF-8 e como reconhecer o padrão de falha.
A resposta API que decodifica para 'Café' - um sintoma concreto de mojibake e os dois bytes atrás dos dois caracteres errados
Uma string Base64 Q2Fmw6k= decodifica em bytes (67, 97, 102, 195, 169), que são UTF-8 texto Café. Cole no decodificador ingênuo (apenas atob e conversão de string) e a saída geralmente é Café, cada acento substituído por dois caracteres errados. Este mojibake acontece porque atob retorna uma sequência de bytes (unidades de código 0–255), não texto UTF-8. Os bytes 195 e 169 codificam é acentuado em UTF-8.
Tratá-los como se fossem caracteres Latin-1 separados fornece o padrão mojibake. O pipeline correto é atob (bytes como string), depois TextDecoder (interpreta bytes como UTF-8) e o texto original volta. A função atob não está quebrada; ele foi projetado para dados binários. Seu nome vem de ASCII-to-binary, e a string binária que ele produz é uma sequência de unidades de código 0–255, cada uma representando um byte.
O que atob() realmente retorna - uma sequência de unidades de código 0–255 que representam bytes, não texto decodificado
Se você alimentá-lo Q2Fmw6k= (Base64 padrão), ele gerará uma string onde cada caractere é um byte: unidade de código 67, então 97, então 102, então 195, então 169. Se exibir essa string diretamente ou interpretar como texto Latin-1, você verá uma saída distorcida. A etapa que falta é converter unidades de código em matriz de bytes e depois decodificar a matriz como UTF-8.
O loop charCodeAt recupera valores de bytes: para cada caractere na saída atob, chame charCodeAt para obter a unidade de código (número 0–255), armazenada em Uint8Array. Assim que existir um array de bytes, passe para TextDecoder com charset utf-8. TextDecoder lê a sequência de bytes e interpreta como texto UTF-8, combinando sequências de bytes como (195, 169) em caracteres únicos como é. Bytes (67, 97, 102, 195, 169) tornam-se uma string Café de quatro caracteres. O loop é deliberadamente chato: leia cada unidade de código retornada com charCodeAt e atribua-a à posição Uint8Array correspondente. Nenhuma decisão de conjunto de caracteres acontece lá. A única interpretação chega quando o TextDecoder recebe esse array e aplica UTF-8 com tratamento de erros fatais.
Transformando essa string em um Uint8Array — o loop charCodeAt e por que é uma cópia de bytes, não uma conversão
Este processo de duas etapas – recuperação de bytes e, em seguida, interpretação UTF-8 – é o que o codificador e decodificador Base64 faz internamente. O padrão mojibake é um sinal revelador desse erro. Se Café aparecer como Café, você verá a interpretação Latin-1 de UTF-8 bytes. UTF-8 bytes para é são 0xC3 0xA9 (decimal 195, 169). Em Latin-1, a unidade de código 195 é Ã e a unidade de código 169 é ©.
Quando a sequência de bytes UTF-8 é lida como se cada byte fosse um caractere latino-1 separado, cada sequência UTF-8 de vários bytes produz caracteres de substituição incorretos. Se Café aparecer como Caf seguido de personagem substituto, ou como Caf? ou Caf mais U+FFFD, você está vendo uma falha diferente: o decodificador não reconheceu a sequência de bytes como UTF-8 válido. Um exemplo concreto: Base64 SGVsbG8sIOS4lueVjCEg8J-Zgg== decodifica da seguinte forma.
TextDecoder e a decisão do conjunto de caracteres - decodificação como UTF-8, e por que o conjunto de caracteres é um fato separado que você deve saber
atob produz string binária com bytes (72, 101, 108, 108, 111, 44, 32, 228, 184, 180, 149, 140, 33, 32, 240, 159, 152, 130). Os primeiros seis bytes são ASCII: tornam-se Olá. Os bytes 228, 184, 180 são uma sequência UTF-8 de três bytes que representa o caractere CJK. Os bytes 149, 140 fazem parte da próxima sequência. A sequência completa inclui sequência de emoji de quatro bytes (240, 159, 152, 130) para o caractere final.
Quando processados corretamente por meio do TextDecoder, todos os bytes se combinam para produzir texto original de script misto. As sequências de bytes UTF-8 têm comprimentos previsíveis: o byte que começa com 0xxxxxxx é um byte único ASCII; o byte começando com 110xxxxx espera o byte seguinte começando com 10xxxxxx (dois bytes no total); byte começando com 1110xxxx espera dois bytes seguintes (três bytes no total); byte começando com 11110xxx espera três bytes seguintes (quatro bytes no total). Para uma amostra mista de CJK e emoji, a visualização de bytes é particularmente diagnóstica porque a intuição de ASCII não ajuda mais. Vários bytes pertencem a cada símbolo visível e uma exclusão de um byte muda a sequência restante para UTF-8 inválido. A decodificação estrita transforma essa mudança em uma falha nomeada, em vez de um dano de aparência plausível.
Exemplo resolvido: decodificação de uma string Base64 contendo CJK e um emoji — bytes, pontos de código e a string final comparada com o original
A sequência que começa com 1111110x é inválida em UTF-8 (reservada para futuro, não usada). Byte começando com 10xxxxxx nunca deve aparecer como byte inicial; é continuação. Se o fluxo de bytes violar as regras, não será UTF-8 válido. TextDecoder com charset utf-8 interpreta o array por essas regras e tem sucesso para sequências válidas. Para inválido, ele relata erro.
O codificador e decodificador Base64 usa TextDecoder com sinalizador de modo estrito verdadeiro. Isso significa que UTF-8 inválido gera erro em vez de inserir caracteres de substituição silenciosamente (U+FFFD). Se a string Base64 for decodificada em bytes que não são válidos UTF-8, o modo estrito será lançado em vez de continuar com o texto ilegível. Esta é uma escolha de design: cargas binárias (imagens, chaves, dados compactados) não são texto e não devem ser decodificadas como texto.
Reconhecendo o padrão: Ã, †e � — como diferenciar um problema Base64 de um problema de conjunto de caracteres
Se tentar decodificar JPEG como Base64, o fluxo de bytes não representará UTF-8 válido e a decodificação estrita irá rejeitá-lo. A ferramenta oferece visualização hexadecimal para essas cargas: você pode ver bytes brutos sem fingir que são texto. Reconhecer erros de decodificação UTF-8 envolve observar os bytes no contexto. Eles são números ímpares onde a sequência de vários bytes é esperada?
O primeiro byte da sequência potencial é inválido (começando com 10xxxxxx)? Estão faltando bytes de continuação? O botão de saída de bytes fornece a bifurcação mais limpa na investigação. Se hex aparecer, mas a decodificação do texto falhar, a análise Base64 foi bem-sucedida e a carga útil é binária, danificada ou codificada com um conjunto de caracteres diferente. A alteração da pontuação Base64 não pode reparar uma incompatibilidade de conjunto de caracteres depois que os bytes corretos já surgiram.
O que isso não cobre — cargas úteis UTF-16, saída binária, como imagens e manipulação de bytes inválidos
Os padrões são consistentes. Um único byte 0xFF nunca é válido em UTF-8; não pode ser byte ASCII (apenas 0–127 são ASCII) e não pode ser byte inicial (bytes iniciais são 0xC0–0xFD, 0xFF é reservado). Substitutos solitários (conceito UTF-16) não podem aparecer em UTF-8; se ver a sequência de bytes 0xED 0xA0 0x80 (que codifica o substituto U+D800 no estilo UTF-8), não é válido UTF-8.
Uma solução alternativa histórica é btoa(unescape(encodeURIComponent(text))). encodeURIComponent transforma café em %C3%A9 (codificação percentual UTF-8 bytes), repacks unescap como unidades de código, btoa codifica unidades de código. Isso funciona para a maioria dos textos, mas é frágil em torno de substitutos solitários e difícil de ler. O pipeline moderno – TextEncoder para bytes e depois base64 – é mais claro e padrão. TextEncoder está integrado em todos os navegadores modernos e Node.js, fazendo a escolha certa. UTF-16, codificações herdadas de byte único e conteúdos de arquivos arbitrários exigem um decodificador selecionado para esses bytes ou um visualizador com reconhecimento de binário. ToolAcre intencionalmente não adivinha entre eles. Adivinhar pode transformar uma sequência inválida em texto enganoso, enquanto um despejo hexadecimal preserva cada byte para uma interpretação informada posterior.
Conclusão: Base64 fornece bytes, UTF-8 fornece texto - como o codificador e decodificador Base64 executa as duas etapas para que o texto decodificado corresponda exatamente à entrada
Quando você tem uma string Base64 e deseja texto UTF-8, as etapas completas são: decodificar Base64 em bytes (usando atob ou biblioteca de decodificação base64), criar Uint8Array a partir de bytes, passar a matriz para TextDecoder com charset utf-8, ler o resultado como string.
Se a entrada for dados binários em vez de texto, ignore o TextDecoder e examine os bytes diretamente. O codificador e decodificador Base64 fornece uma visualização de bytes hexadecimais, preservando valores que a decodificação UTF-8 estrita rejeitaria. Essa bifurcação é um diagnóstico: bytes bem-sucedidos mais texto com falha significam que a análise Base64 funcionou, enquanto a carga útil é binária, danificada ou codificada com um conjunto de caracteres que esta ferramenta não adivinha.