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 codificação de comprimento variável que virou padrão da web
O UTF-8 e a codificação de caracteres dominante na internet — em 2024 ja passa de 98% de todas as páginas. Desenhado por Ken Thompson e Rob Pike em 1992 e padronizado como RFC 3629 (2003), resolve um problema difícil de compatibilidade: codificar todo o catálogo Unicode (atualmente 154.998 code points atribuídos até U+10FFFF) mantendo-se compatível 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 codificação de comprimento variável. 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 históricas).
Os bytes de continuacao começam sempre com o padrão 10, o que torna o fluxo auto-sincronizavel: um parser pode cair em qualquer posição e encontrar o próximo byte lider em até três passos. O português 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 sequência de bytes invalida
Um validador UTF-8 estrito rejeita seis famílias de sequências mal formadas:
- Byte de continuacao solto — qualquer
10xxxxxxsem byte lider antes. - Sequência truncada — byte lider que promete 2/3/4 bytes mas não entrega todos.
- Codificação overlong — codificar um code point com mais bytes do que o mínimo necessário (por exemplo
C0 80para NUL e proibido; algumas APIs Java antigas abusaram disso como "modified UTF-8"). - Surrogate code points —
U+D800aU+DFFFsão 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 inválidos —
0xC0,0xC1,0xF5–0xFFnunca podem começar uma sequência UTF-8 legitima.
Ferramentas de segurança dependem de validação 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 três bytes EF BB BF (forma codificada de U+FEFF). Diferente de UTF-16, a ordem de bytes não tem significado em UTF-8, então 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 início da resposta, quebrando chamadas header(); esse bug histórico e uma das razoes para "sem BOM" ser o default mais seguro.
Canais de declaração 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 último recurso de detecção.
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 não e compatível com ASCII e depende de endianness. O UTF-32 usa 4 bytes fixos — fácil indexar mas desperdica memória. O ISO-8859-1 (Latin-1) e o Windows-1252 são codificacoes legadas de byte único 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
Até a versão 8 do MySQL, o alias utf8 era secretamente utf8mb3: somente até 3 bytes, o que silenciosamente quebrava emoji e code points suplementares. A correção 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 conexão — caso contrário a cadeia vaza para utf8mb3 em algum salto e corrompe os dados.
Mojibake, dupla codificação e como detectar
Mojibake e o lixo visível que surge quando bytes são decodificados com o charset errado. Sintoma clássico em português: "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 detecção incluem checar sequências impossiveis (por exemplo C3 83 C2 A1 para "á"), rodar detectores como chardet / ICU e inspecionar a razão entre tamanho em bytes e número de caracteres. Esta ferramenta valida estritamente e mostra o detalhamento dos bytes para você identificar o problema na origem.
FAQ
O BOM e obrigatório em arquivos UTF-8? Não. 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 sequências ZWJ combinam vários code points de 4 bytes.
No MySQL escolho utf8 ou utf8mb4? Sempre utf8mb4. O alias "utf8" puro e um erro histórico e quebra silenciosamente emoji e caracteres suplementares.
Por que meu texto em português aparece como "?" ou "é" no banco? Charset mismatch na insercao. Ou a conexão 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 necessário.
Um byte isolado pode ser UTF-8 válido? Apenas se estiver no intervalo 00–7F. Qualquer byte entre 80 e FF sozinho e inválido — precisa fazer parte de uma sequência 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.
Validador de Magnet Link
Valida o formato de magnet links (magnet:?xt=urn:btih:...) e extrai parâmetros: hash, nome do torrent, trackers e tamanho.
Validador de IP (v4 e v6)
Valide endereços IPv4 e IPv6 com detecção automática. Mostra a classe (A/B/C/D/E), se é privado ou público, loopback, multicast e formato canônico. Tudo no navegador.
Validador de RG
Valide números de RG no formato SP (9 dígitos + dígito verificador). Verificação no navegador, sem enviar dados para servidores.