Glossary
UTF-8
A codificação de caracteres da web
By Buğra SözeriPublished Updated
UTF-8 (Unicode Transformation Format, 8 bits) é uma codificação de largura variável para caracteres Unicode. Cada ponto de código codifica para 1 a 4 bytes dependendo do seu valor: caracteres ASCII (U+0000 a U+007F) ocupam um byte; extensões latinas comuns e grego/cirílico dois; ideogramas CJK três; emojis e scripts raros quatro.
Projetado por Ken Thompson e Rob Pike em 1992, principalmente para o Plan 9. Propriedades-chave:
- Compatível com ASCII. Texto puro ASCII é UTF-8 válido byte a byte.
- Auto-sincronizante. Se um fluxo for corrompido no meio de um caractere, o decodificador pode encontrar o próximo limite de caractere sem retroceder.
- Sem problema de ordem de bytes. Os bytes são processados da esquerda para a direita; não há distinção entre big-endian e little-endian.
- Compacto para scripts latinos, menos compacto que UTF-16 para conteúdo predominantemente CJK (3 bytes por caractere vs 2).
UTF-8 é a codificação dominante na web — mais de 98% das páginas em 2024. É o padrão para HTML5, JSON (onde a especificação RFC 8259 realmente exige UTF-8) e praticamente todos os protocolos modernos. Codificações antigas (Windows-1252, ISO-8859-1, Shift-JIS) sobrevivem em sistemas legados, mas devem ser convertidas na entrada de qualquer pilha moderna.
A controvérsia do BOM (Byte Order Mark): UTF-16 e UTF-32 usam um BOM de 2 ou 4 bytes no início de um arquivo para declarar a ordem dos bytes, mas UTF-8 não tem ordem de bytes a marcar. As ferramentas da Microsoft habitualmente adicionam um BOM UTF-8 de 3 bytes (EF BB BF) de qualquer forma, enquanto as ferramentas Unix normalmente não fazem isso. O resultado: scripts shell salvos pelo Notepad quebram, importações de CSV mostram lixo invisível na primeira célula, e analisadores YAML/JSON rejeitam o arquivo. O padrão Unicode tolera, mas não exige, um BOM UTF-8; a recomendação moderna é “não adicione um.” Se você receber um arquivo com um, remova-o na leitura.
Comprimento de string vs comprimento de bytes — o problema sempre relevante: na maioria das linguagens, "hello".length retorna 5 (caracteres), mas Buffer.byteLength("hello", "utf8") retorna 5 (bytes — igual para ASCII). Para "café", o comprimento de caracteres é 4, mas o comprimento de bytes é 5 (o é tem 2 bytes). Para "🎉", o comprimento de caracteres em JavaScript é 2 (par substituto), mas o comprimento de bytes é 4 e o comprimento de grafema é 1. Truncar strings UTF-8 por contagem de bytes sem percepção de grafema regularmente produz mojibake — a correção padrão é usar a API Intl.Segmenter (navegadores modernos) ou o pacote npm graphemer. Referência: RFC 3629 — UTF-8, um formato de transformação do ISO 10646.
Exemplo prático
Codifique a string “A€🎉”. Ponto de código de cada caractere e sequência de bytes UTF-8: A (U+0041) → 1 byte 0x41. € (U+20AC) → 3 bytes 0xE2 0x82 0xAC (os bits altos codificam o comprimento: 1110xxxx 10xxxxxx 10xxxxxx). 🎉 (U+1F389) → 4 bytes 0xF0 0x9F 0x8E 0x89. Total: 8 bytes para 3 caracteres. Em uma coluna de banco de dados declarada como VARCHAR(10) com semântica de caracteres UTF-8 (PostgreSQL moderno, MySQL com utf8mb4), isso cabe confortavelmente. Em uma coluna de bytes fixos declarada como VARCHAR(10) BYTES (MySQL mais antigo com utf8 que era na verdade limitado a 3 bytes), a codificação de 4 bytes do emoji não cabe — o modo de falha canônico “não consigo armazenar emoji no MySQL”. A correção no MySQL desde 5.5.3 é usar utf8mb4 como charset da coluna e da conexão.
Quando e por que isso importa
Cada byte que você processa na web moderna provavelmente é UTF-8, mas várias camadas ainda erram. Requisições HTTP sem um Content-Type: text/...; charset=utf-8 explícito podem ter como padrão ISO-8859-1 em proxies mais antigos; trabalhos ETL de mainframe legados entregam arquivos EBCDIC que devem ser transcodificados na ingestão; a saída do console do Windows tem como padrão a página de código do sistema (CP-1252 na maioria das instalações em inglês americano) e corrompe texto canalizado sem um chcp 65001 primeiro. A prática defensiva: declare UTF-8 explicitamente em todos os lugares (HTML <meta charset="utf-8">, cabeçalhos HTTP, pragmas de codificação de arquivo, charsets de conexão de banco de dados) e valide quaisquer bytes de entrada contra a gramática UTF-8 — sequências de bytes inválidas são um sinal confiável de uma incompatibilidade de charset a montante. Referência: Padrão de Codificação WHATWG.
Frequently asked questions
- O que é UTF-8?
- UTF-8 é uma codificação Unicode de largura variável que representa cada ponto de código usando 1 a 4 bytes. Caracteres ASCII (U+0000 a U+007F) usam exatamente 1 byte, tornando o UTF-8 totalmente compatível com versões anteriores do ASCII. É a codificação dominante na web, usada por mais de 98% das páginas.
- Como funciona a codificação UTF-8 na prática?
- A letra latina A (U+0041) é armazenada como um único byte 0x41. O emoji de rosto sorridente (U+1F600) requer 4 bytes: 0xF0 0x9F 0x98 0x80. Esse design significa que texto em inglês armazenado como ASCII também é UTF-8 válido, e texto multilíngue é tratado adicionando mais bytes apenas quando necessário.
- Qual é a diferença entre UTF-8 e UTF-16?
- UTF-8 usa 1 a 4 bytes e é compatível com ASCII, tornando-o ideal para armazenamento web e em arquivos. UTF-16 usa 2 ou 4 bytes e é comum internamente no Windows e Java. UTF-8 é mais eficiente em espaço para texto rico em ASCII; UTF-16 usa os mesmos 2 bytes para a maioria dos caracteres CJK comuns, enquanto UTF-8 usa 3.
Related
Published May 14, 2026 · Last reviewed May 31, 2026