FNSP Web Page

Porque é que aparece "ç" em vez de "ç"

Aparece num site antigo, numa importação de CSV, num email. E não é um caractere estranho — é a mesma letra, lida com a tabela errada.

1. O que se passa

Em UTF-8, o "ç" não cabe num byte: são dois, 0xC3 e 0xA7. Se alguém ler esses dois bytes como se fossem Latin-1 — uma tabela onde cada byte é uma letra — vê duas letras:

ç  →  UTF-8  →  C3 A7  →  lido como Latin-1  →  ç

Daí o padrão. O "Ã" à frente de tudo é a assinatura de texto UTF-8 lido como se não fosse.

  • ç era ç

  • ã era ã

  • ê era ê

2. Onde é que a tabela se perde

A cadeia tem muitos elos, e basta um estar errado:

  • A ligação à base de dados — o cliente diz um encoding e a tabela está noutro.

  • A coluna. Em MySQL, utf8 nunca foi UTF-8 a sério: são três bytes no máximo e não chega para emojis. O correto é utf8mb4.

  • O cabeçalho da resposta: Content-Type: text/html; charset=utf-8.

  • O ficheiro CSV que o Excel gravou em Windows-1252 sem avisar ninguém.

3. O caso mau: dupla codificação

Acontece quando texto já estragado é guardado outra vez como UTF-8. Aí o "ç" vira ele próprio dois caracteres, e o estrago passa a ter camadas:

ç  →  ç  →  ç

Reparar isto é desfazer as camadas pela ordem inversa — e é preciso saber quantas são. É por isso que a correção se faz uma vez, numa cópia, com contagem antes e depois.

// Desfazer uma camada: ler os bytes como Latin-1 e reinterpretar como UTF-8
const reparado = Buffer.from(estragado, 'latin1').toString('utf8');

4. A prevenção

UTF-8 em todos os elos, sem exceção: base, ligação, ficheiros, cabeçalhos, editor. E validar no sítio onde os dados entram — é infinitamente mais barato recusar um ficheiro mal codificado do que reparar uma tabela seis meses depois, quando já ninguém sabe quantas camadas tem.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.