Também disponível em: English · Español · Français · العربية
Codificação de caracteres: todos os charsets do navegador
A lista completa que um navegador deve suportar, um decodificador que roda no seu e o que cada rótulo realmente resolve.
O que é uma codificação de caracteres?
Um arquivo guarda bytes. Uma codificação de caracteres é o acordo que transforma esses bytes em letras: que o byte 0x41 é A, que os dois bytes 0xC3 0xA9 são é. Erre o acordo e vem o mojibake — os mesmos bytes lidos pela tabela errada, produzindo é onde deveria haver é.
Houve centenas desses acordos, um por idioma e por fabricante. A web os estreitou: o Encoding Standard da WHATWG lista exatamente 40 codificações e os 228 rótulos que as nomeiam, e é aquela raridade que é uma lista que não pode crescer. Ele diz nas próprias palavras: a tabela reúne todas as codificações e rótulos que um agente de usuário deve suportar, e ele não deve suportar nenhum outro. Uma das 40 é a atual. As outras 39 ficam sob títulos que começam pela palavra legadas.
Esse fechamento é o que separa esta lista de qualquer registro com que se pareça. Um registro anota o que existe e ganha linhas. Esta é um teto.
Como usar
- Coloque alguns bytes. Dígitos hexadecimais são lidos como bytes, então 93 77 6f 72 6c 64 94 são sete deles. Qualquer outra coisa é tratada como texto e codificada antes em UTF-8, porque UTF-8 é a única coisa que um navegador sabe codificar.
- Nomeie uma codificação. Vale qualquer um dos 228 rótulos, em qualquer caixa. Um rótulo não reconhecido é uma falha e não um retorno silencioso a outra coisa, que é o que o padrão exige.
- Leia a comparação abaixo. Os mesmos bytes são decodificados sob quatro rótulos diferentes que resolvem para uma só codificação, então as quatro linhas saem idênticas — e é justamente esse o ponto.
Não existe codificação ASCII, nem Latin-1
Peça ascii a um navegador e receba windows-1252. Peça us-ascii, iso-8859-1, latin1, cp819 ou ansi_x3.4-1968 e receba windows-1252 de novo. Dezessete dos 228 rótulos se empilham naquela linha, e nem ASCII nem ISO-8859-1 existem no padrão com nome próprio — enquanto ISO-8859-2 e ISO-8859-15 existem, o que faz da ausência uma decisão e não um descuido.
Importa porque windows-1252 não é ISO-8859-1. Decodificando todos os 256 valores de byte pelas duas definições, elas diferem em 27, e os 27 caem na faixa 0x80 a 0x9F, que a ISO-8859-1 preenche com códigos de controle invisíveis e a Microsoft preencheu com pontuação. O byte 0x80 é o símbolo do euro. De 0x91 a 0x94 estão as aspas curvas. 0x96 e 0x97 são o traço e o travessão. 0x85 são as reticências.
Ou seja, os caracteres em que as duas discordam são exatamente os que um processador de texto insere sem ser pedido, e por isso um documento salvo como Latin-1 e servido como Latin-1 continua exibindo as aspas certas: o navegador nunca esteve usando Latin-1. Cinco dos valores que a Microsoft deixou vazios permanecem como caracteres de controle em vez de virarem U+FFFD, então nada naquela faixa jamais falha ao decodificar.
Isso também limita o quanto se pode confiar que uma codificação de um byte seja total: entre as 28 codificações de um byte há 150 posições sem caractere algum, que decodificam para U+FFFD, espalhadas por nove delas. Que todo byte seja um caractere é uma suposição razoável e falsa.
Ler quarenta, escrever uma
Um navegador decodifica todas as 40. Codifica exatamente uma. O padrão fixa a propriedade encoding de um codificador de texto em utf-8 e não dá argumento nenhum ao construtor, então não há forma suportada de pedir que um navegador escreva Shift_JIS ou windows-1251. A seção 4.3 leva a mesma regra adiante: quando a análise de uma URL ou o envio de um formulário precisam de uma codificação de saída, replacement e as duas UTF-16 são reescritas para UTF-8 antes de qualquer escrita.
Uma entrada é mais estranha que as outras. A codificação chamada replacement não decodifica nada: qualquer entrada não vazia vira um único U+FFFD. Seis rótulos apontam para ela, cinco deles codificações reais e implantadas — ISO-2022-CN, ISO-2022-KR, HZ-GB-2312 e seus apelidos. O padrão diz claramente por quê: ela existe para impedir ataques que abusam do descompasso entre as codificações que um servidor suporta e as que um cliente suporta. A ISO-2022-JP sobreviveu à mesma poda apenas porque conteúdo demais depende dela.
E um rótulo responde a uma pergunta que as pessoas erram: utf-16, sem indicar a ordem dos bytes, significa little-endian. O rótulo unicode também.
O que esta página não consegue dizer
O decodificador aqui é o do seu navegador, não o nosso, e isso é deliberado: é a única implementação cuja resposta importa para você, e é aquela para a qual o padrão foi escrito. Também significa que o resultado pode diferir de outro ambiente. O Node, por exemplo, recusa a codificação replacement de saída, mesmo o padrão exigindo suporte a ela, então algo que decodifica aqui pode não decodificar num script.
Segundo, esta página diz o que um rótulo significa, não o que um arquivo é. Nada dentro de uma sequência de bytes diz qual codificação a produziu; adivinhar é um problema separado e bem mais difícil, e a resposta honesta para qualquer arquivo sob seu controle é convertê-lo para UTF-8 e parar de adivinhar.
Terceiro, este é um padrão da web. Bancos de dados, terminais e linguagens de programação implementam as próprias tabelas e nem sempre concordam. Comparadas byte a byte com os codecs do Python nas 28 codificações de um byte, 18 são idênticas e as demais diferem em 89 de 7.168 posições, quase sempre onde o Python recusa um byte que a Microsoft deixou indefinido e um navegador devolve um caractere de controle. Resta uma discordância real, em duas posições do KOI8-U, onde os dois projetos herdaram versões diferentes da mesma codificação.
Por que é grátis?
A tabela são alguns kilobytes que viajam com a página, e a decodificação é feita pelo navegador que você já tem. Nada do que você digita é enviado, nada é registrado e não há conta a criar.
Sem cadastro, sem limites e sem marca d'água em nada que você copiar.