Validador de UTF-8
Verifica se uma sequência de bytes (em hex) é UTF-8 válida — útil para depurar encoding de arquivos. Mostra o texto decodificado se válido.
UTF-8: a codificacao de comprimento variavel que virou padrao da web
O UTF-8 e a codificacao de caracteres dominante na internet — em 2024 ja passa de 98% de todas as paginas. Desenhado por Ken Thompson e Rob Pike em 1992 e padronizado como RFC 3629 (2003), resolve um problema dificil de compatibilidade: codificar todo o catalogo Unicode (atualmente 154.998 code points atribuidos ate U+10FFFF) mantendo-se compativel byte a byte com ASCII de 7 bits. Essa compatibilidade retroativa explica por que todo sistema operacional, navegador, banco e protocolo moderno adotou UTF-8 como default seguro.
Como o UTF-8 codifica um code point em 1 a 4 bytes
UTF-8 e uma codificacao de comprimento variavel. Um byte lider anuncia quantos bytes de continuacao vem depois, e cada byte de continuacao contribui com 6 bits adicionais de payload:
- 1 byte —
0xxxxxxx— code pointsU+0000aU+007F(ASCII puro). - 2 bytes —
110xxxxx 10xxxxxx—U+0080aU+07FF(latim estendido, grego, cirilico, hebraico, arabe). - 3 bytes —
1110xxxx 10xxxxxx 10xxxxxx—U+0800aU+FFFF(BMP — ideogramas chines/japones/coreano, maioria dos sistemas vivos). - 4 bytes —
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx—U+10000aU+10FFFF(planos suplementares, emoji, escritas historicas).
Os bytes de continuacao comecam sempre com o padrao 10, o que torna o fluxo auto-sincronizavel: um parser pode cair em qualquer posicao e encontrar o proximo byte lider em ate tres passos. O portugues brasileiro fica na faixa de 2 bytes — á = C3 A1, é = C3 A9, ç = C3 A7, ã = C3 A3.
"Olá" -> 4F 6C C3 A1 (3 chars, 4 bytes)
"日本" -> E6 97 A5 E6 9C AC (2 chars, 6 bytes)
"😀" -> F0 9F 98 80 (1 char, 4 bytes)
O que torna uma sequencia de bytes invalida
Um validador UTF-8 estrito rejeita seis familias de sequencias mal formadas:
- Byte de continuacao solto — qualquer
10xxxxxxsem byte lider antes. - Sequencia truncada — byte lider que promete 2/3/4 bytes mas nao entrega todos.
- Codificacao overlong — codificar um code point com mais bytes do que o minimo necessario (por exemplo
C0 80para NUL e proibido; algumas APIs Java antigas abusaram disso como "modified UTF-8"). - Surrogate code points —
U+D800aU+DFFFsao reservados para pares substitutos do UTF-16 e nunca devem aparecer em UTF-8. - Code point fora do intervalo — qualquer coisa acima de
U+10FFFF, que demandaria 5 ou 6 bytes (banido pela RFC 3629). - Bytes lideres invalidos —
0xC0,0xC1,0xF5–0xFFnunca podem comecar uma sequencia UTF-8 legitima.
Ferramentas de seguranca dependem de validacao estrita: overlong encodings ja foram usados para contrabandear path traversals ../ em filtros ingenuos (worm Nimda contra o IIS).
BOM, declaracoes e o header de charset
O Byte Order Mark em UTF-8 e o prefixo de tres bytes EF BB BF (forma codificada de U+FEFF). Diferente de UTF-16, a ordem de bytes nao tem significado em UTF-8, entao o BOM e apenas um sinal — e opcional. A spec do HTML5 inclusive recomenda omiti-lo, enquanto muitas ferramentas Windows (Notepad, exports antigos de CSV do Excel) insistem em grava-lo. Servidores PHP antigos vazavam o BOM no inicio da resposta, quebrando chamadas header(); esse bug historico e uma das razoes para "sem BOM" ser o default mais seguro.
Canais de declaracao em ordem de prioridade:
- Header HTTP:
Content-Type: text/html; charset=UTF-8— vence o documento. <meta charset="UTF-8">do HTML5 nos primeiros 1024 bytes do<head>.- Prologo XML:
<?xml version="1.0" encoding="UTF-8"?>. - BOM como ultimo recurso de deteccao.
UTF-8 vs UTF-16 vs UTF-32 e o legado do ISO-8859-1 / Windows-1252
O UTF-16 usa 2 ou 4 bytes por code point e e o formato nativo de strings dentro do Windows, do Java e dos engines JavaScript (a V8 guarda strings em 16 bits internamente). Fora desses runtimes UTF-16 e raro porque nao e compativel com ASCII e depende de endianness. O UTF-32 usa 4 bytes fixos — facil indexar mas desperdica memoria. O ISO-8859-1 (Latin-1) e o Windows-1252 sao codificacoes legadas de byte unico ainda presentes em bancos brasileiros antigos; converte-las para UTF-8 normalmente exige iconv ou ICU explicitos.
utf8 vs utf8mb4 no MySQL — a armadilha que comeu emoji
Ate a versao 8 do MySQL, o alias utf8 era secretamente utf8mb3: somente ate 3 bytes, o que silenciosamente quebrava emoji e code points suplementares. A correcao e o alias utf8mb4 com collation utf8mb4_0900_ai_ci ou utf8mb4_unicode_520_ci. Sempre declare CHARACTER SET utf8mb4 no CREATE DATABASE, CREATE TABLE, no my.cnf, na URL JDBC e no SET NAMES da conexao — caso contrario a cadeia vaza para utf8mb3 em algum salto e corrompe os dados.
Mojibake, dupla codificacao e como detectar
Mojibake e o lixo visivel que surge quando bytes sao decodificados com o charset errado. Sintoma classico em portugues: "olá" renderizado como "olá" porque os bytes UTF-8 (C3 A1) foram lidos como Latin-1 e depois re-codificados em UTF-8. Heuristicas de deteccao incluem checar sequencias impossiveis (por exemplo C3 83 C2 A1 para "á"), rodar detectores como chardet / ICU e inspecionar a razao entre tamanho em bytes e numero de caracteres. Esta ferramenta valida estritamente e mostra o detalhamento dos bytes para voce identificar o problema na origem.
FAQ
O BOM e obrigatorio em arquivos UTF-8? Nao. A RFC 3629 e a spec do HTML5 recomendam omitir. So use se o consumidor exigir explicitamente (alguns fluxos de CSV no Excel para Windows).
Emoji precisa mesmo de 4 bytes? Sim, praticamente todos. Emoji vivem nos planos suplementares a partir de U+1F000, codificados em UTF-8 com a forma de 4 bytes. Modificadores de tom de pele e sequencias ZWJ combinam varios code points de 4 bytes.
No MySQL escolho utf8 ou utf8mb4? Sempre utf8mb4. O alias "utf8" puro e um erro historico e quebra silenciosamente emoji e caracteres suplementares.
Por que meu texto em portugues aparece como "?" ou "é" no banco? Charset mismatch na insercao. Ou a conexao esta com charset errado (defina charset=utf8mb4 no DSN) ou os dados ja chegaram em mojibake na origem. Conserte a pipeline e depois re-encode com iconv -f LATIN1 -t UTF-8 se necessario.
Um byte isolado pode ser UTF-8 valido? Apenas se estiver no intervalo 00–7F. Qualquer byte entre 80 e FF sozinho e invalido — precisa fazer parte de uma sequencia multi-byte.
Ferramentas Relacionadas
Validador de Base91
Verifica se uma string usa apenas caracteres Base91 (letras, dígitos e símbolos específicos como !#$%&()*+...). Não decodifica, apenas valida formato.
Validador de Chave NFe
Valida chaves de acesso de NF-e/CT-e/NFC-e (44 dígitos) com mod-11, UF e modelo. Decompõe os campos para auditoria fiscal.
Validador de Chave Pix
Valida chaves Pix de qualquer tipo: CPF, CNPJ, email, telefone (+55) ou chave aleatória (UUID). Detecta o tipo automaticamente.