# Inspetor Unicode

> Veja o que há de fato num texto: cada ponto de código com o seu nome, e os caracteres que se escondem ou enganam, de espaços de largura zero e controles bidirecionais do Trojan Source a letras cirílicas fingindo ser latinas. Consulte qualquer ponto de código, encontre um pelo nome, limpe um texto e escreva-o como escapes em oito linguagens.

- Tool: https://ronutz.com/pt-BR/tools/unicode-inspector
- Family: Codificação e dados

---

## O que faz

Um texto pode conter muito mais do que mostra. Um espaço de largura zero fica entre duas letras sem deixar rastro, um override da direita para a esquerda faz uma linha de código aparecer numa ordem diferente da que o compilador lê, um "а" cirílico passa por um "a" latino, e um separador de linha começa uma nova linha no seu editor, mas não no seu analisador. O inspetor mostra o que de fato está ali, um ponto de código por vez.

Ele tem três modos:

- **Inspecionar um texto** conta o texto, diz se algo merece atenção, lista o que encontrou por tipo, aponta controles bidirecionais deixados abertos no fim de uma linha e palavras que misturam escritas, desenha o texto na ordem em que está armazenado com cada caractere escondido como uma etiqueta, lista todos os pontos de código, oferece uma cópia limpa e escreve o texto como escapes em oito linguagens.
- **Um ponto de código** recebe um ponto de código em qualquer notação (`U+00E9`, `é`, `0xE9`, `&eacute;`, `é`, `zero width space`, `BOM`) e mostra o nome e os apelidos, as propriedades, as codificações, os escapes e o que é preciso saber sobre ele.
- **Encontrar pelo nome** lista os pontos de código cujo nome ou apelido tem palavras que começam com as palavras digitadas.

## O que ele aponta num texto

| Achado | O que é | Por que importa |
|---|---|---|
| Controle bidirecional | Um dos doze caracteres Bidi_Control (LRM, RLM, ALM, LRE, RLE, LRO, RLO, PDF, LRI, RLI, FSI, PDI) | Muda a ordem exibida do texto ao redor; a classe de ataque Trojan Source (CVE-2021-42574) |
| Aberto no fim da linha | Um embedding, override ou isolate sem PDF ou PDI antes de a linha acabar | Tudo o que vem depois nessa linha pode ser exibido numa ordem diferente da ordem em que é lido |
| Invisível | Default_Ignorable_Code_Point: caracteres de largura zero, o BOM, seletores de variação, tags | Não desenha nada, mas comparações de strings, comprimentos e hashes o enxergam |
| Controle | Um código de controle que não é TAB, LF nem CR | Não é texto; as ferramentas o descartam, mostram uma caixa ou param |
| Quebra de linha que não é LF nem CR | VT, FF, NEL (U+0085), LINE SEPARATOR (U+2028), PARAGRAPH SEPARATOR (U+2029) | Um editor e uma linguagem podem discordar sobre onde a linha termina (UTS #55, falsificação por quebra de linha) |
| Surrogate isolado, não caractere | Pontos de código que não são caracteres | Inválidos em UTF-8 (surrogates) ou nunca destinados a intercâmbio (não caracteres) |
| Uso privado, não atribuído | Sem significado público, ou ainda sem caractere | Fontes e sistemas divergem, ou o texto veio de um Unicode mais novo que o seu |
| Caractere de substituição | U+FFFD | Muitas vezes marca uma falha de decodificação anterior |
| Espaço, aspa ou traço não ASCII | Espaços não separáveis e outros, aspas tipográficas, travessões e meias-riscas, o sinal de menos | Parecem ASCII; analisadores e comparações discordam |
| Confundível com ASCII | Um caractere que a UTS #39 associa a um protótipo ASCII | Sósias: а cirílico por a, ο grego por o |
| ASCII estilizado | Um caractere cuja decomposição de compatibilidade é ASCII | Letras de largura total, ligaduras e parecidos |
| Palavra de escritas misturadas | Uma palavra cujas letras não compartilham um sistema de escrita | `pаypal` com um а cirílico; japonês misturando Han, Hiragana e Katakana não é apontado |

A detecção de escritas misturadas segue a UTS #39: o conjunto de escritas aumentado de cada caractere é o seu Script_Extensions mais os sistemas de escrita que combinam escritas (Han acrescenta Hanb, Hntl, Jpan e Kore; Hiragana e Katakana acrescentam Jpan; Hangul acrescenta Kore; Bopomofo acrescenta Hanb; Latin acrescenta Hntl), um caractere Common ou Inherited combina com qualquer escrita, e uma palavra é misturada quando a interseção desses conjuntos sobre os seus caracteres é vazia.

## O texto, na ordem armazenada

O painel de revelação desenha o texto da esquerda para a direita na ordem da memória, com a reordenação bidirecional desligada para o próprio painel, então nenhum controle do texto consegue reordenar o que você vê. Cada caractere que merece atenção vira uma etiqueta com o seu ponto de código; etiquetas vermelhas mudam significado ou ordem, etiquetas âmbar imitam outra coisa. Passe o mouse ou o foco sobre uma etiqueta para ver o nome.

## Limpeza

A cópia limpa pode remover caracteres invisíveis e bidirecionais, trocar espaços não ASCII por SPACE (e LINE SEPARATOR, PARAGRAPH SEPARATOR e NEL por LF), transformar aspas tipográficas e traços em `'`, `"` e `-`, e, se você pedir, trocar sósias pelo ASCII que imitam. Essa última opção vem desligada, porque também altera palavras legítimas em cirílico, grego e outras escritas.

## Escapes

O texto inteiro pode ser escrito em JSON, JavaScript, Python, HTML, CSS, numa URL, numa string `u8` de C ou numa palavra entre aspas de Tcl (iRules). Cada forma faz o escape dos caracteres que a sua linguagem reserva e de tudo o que está fora do ASCII imprimível. Quando esta ferramenta foi construída, cada forma de 4.000 pontos de código, espalhados pelos dezessete planos, e de dois textos de estresse foi decodificada de volta pela própria linguagem (CPython, Node, GCC, Tcl 8.4.6, e o Chromium para HTML e CSS), e todos voltaram iguais.

Algumas formas não comportam todos os caracteres, e a ferramenta diz isso em vez de escrever algo errado:

- **Tcl 8.4 e iRules** não têm escape para caracteres além de U+FFFF: `\u` aceita no máximo quatro dígitos hexadecimais, e o interpretador Tcl 8.4.6 lê os quatro bytes UTF-8 de um caractere assim como quatro caracteres separados.
- **HTML** não comporta um surrogate isolado, e uma referência de U+0080 a U+009F dá outro caractere: 27 dessas 32 referências são lidas como Windows-1252 (`&#x85;` vira reticências), então a ferramenta escreve esses caracteres como eles mesmos.
- **CSS** transforma um 0 ou um surrogate escapado em U+FFFD.
- **C**: nomes de caractere universais não podem nomear caracteres abaixo de U+00A0 além de `$`, `@` e `` ` ``, nem um surrogate; a ferramenta escreve os bytes UTF-8 de U+0080 a U+009F em octal.
- **URLs** codificam por porcentagem bytes UTF-8, que um surrogate isolado não tem.

## Um ponto de código

- **Nome.** A propriedade Name; para um controle, o seu primeiro apelido formal (controles não têm nome); para qualquer outro sem nome, o seu rótulo de ponto de código, como `<surrogate-D800>` ou `<reserved-0378>`.
- **Apelidos.** Todos os apelidos formais com o seu tipo: correção, controle, alternativo, fictício ou abreviação (`BOM` e `ZWNBSP` para U+FEFF).
- **Propriedades.** General_Category, Block, Script e Script_Extensions, e a versão do Unicode que o incluiu.
- **Codificações.** Bytes UTF-8, unidades de código UTF-16 (um par surrogate além de U+FFFF) e UTF-32.
- **Escapes e referências.** As oito formas acima para este ponto de código, mais as referências HTML decimal, hexadecimal e nomeadas, com uma nota quando uma referência não devolve este ponto de código.

## Limites

- Colunas e posições são contadas em pontos de código. Editores podem contar unidades UTF-16 ou caracteres percebidos pelo usuário.
- A detecção de escritas misturadas trabalha palavra por palavra; não verifica identificadores inteiros através de pontuação e não decide se uma mistura é legítima.
- Os dados de confundíveis cobrem caracteres que parecem texto ASCII. Confundíveis entre duas escritas não ASCII ficam de fora.
- A ferramenta mostra a visão do Unicode 18.0.0. Um sistema com dados mais antigos pode não conhecer caracteres incluídos depois (13.007 chegaram na 18.0).

## Fontes

- [Unicode Character Database 18.0.0](https://www.unicode.org/Public/18.0.0/ucd/): UnicodeData.txt, DerivedName.txt, NameAliases.txt, PropList.txt, DerivedCoreProperties.txt, Blocks.txt, DerivedAge.txt, Scripts.txt, ScriptExtensions.txt, LineBreak.txt, PropertyValueAliases.txt (lido em 2026-10-03)
- [UTS #39: Unicode Security Mechanisms (18.0.0) e confusables.txt](https://www.unicode.org/reports/tr39/) (lido em 2026-10-03)
- [UTS #55: Unicode Source Code Handling](https://www.unicode.org/reports/tr55/) (lido em 2026-10-03)
- [UAX #9: Unicode Bidirectional Algorithm](https://www.unicode.org/reports/tr9/) (lido em 2026-10-03)
- [UAX #44: Unicode Character Database](https://www.unicode.org/reports/tr44/) (lido em 2026-10-03)
- [The Unicode Standard 18.0.0, capítulos 3, 4, 5 e 23](https://www.unicode.org/versions/Unicode18.0.0/) (lido em 2026-10-03)
- [NVD: CVE-2021-42574](https://nvd.nist.gov/vuln/detail/CVE-2021-42574) (lido em 2026-10-03)
- [RFC 3629: UTF-8](https://www.rfc-editor.org/rfc/rfc3629) (lido em 2026-10-03)
- [RFC 2781: UTF-16](https://www.rfc-editor.org/rfc/rfc2781) (lido em 2026-10-03)
- [RFC 8259: JSON](https://www.rfc-editor.org/rfc/rfc8259) (lido em 2026-10-03)
- [ECMA-262: ECMAScript Language Specification](https://tc39.es/ecma262/) (lido em 2026-10-03)
- [The Python Language Reference: Lexical analysis](https://docs.python.org/3/reference/lexical_analysis.html) (lido em 2026-10-03)
- [ISO/IEC 9899:2011, rascunho do comitê N1570 (C11), 6.4.3](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) (lido em 2026-10-03)
- [Manual do Tcl 8.4: Tcl](https://www.tcl-lang.org/man/tcl8.4/TclCmd/Tcl.htm) (lido em 2026-10-03)
- [WHATWG HTML: análise (referências numéricas de caractere)](https://html.spec.whatwg.org/multipage/parsing.html) (lido em 2026-10-03)
- [WHATWG HTML: referências de caractere nomeadas](https://html.spec.whatwg.org/entities.json) (lido em 2026-10-03)
- [RFC 3986: URI Generic Syntax](https://www.rfc-editor.org/rfc/rfc3986) (lido em 2026-10-03)

## Standards and references

- [Unicode Character Database 18.0.0: UnicodeData.txt](https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt) - character names and compatibility decompositions
- [Unicode Character Database 18.0.0: PropList.txt](https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt) - the White_Space, Quotation_Mark and Dash properties
- [Unicode Character Database 18.0.0: DerivedCoreProperties.txt](https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt) - the Default_Ignorable_Code_Point property
- [Unicode Character Database 18.0.0: extracted/DerivedName.txt](https://www.unicode.org/Public/18.0.0/ucd/extracted/DerivedName.txt) - every character name, checked code point by code point
- [Unicode Character Database 18.0.0: NameAliases.txt](https://www.unicode.org/Public/18.0.0/ucd/NameAliases.txt) - formal aliases: corrections, control names, alternates, figments, abbreviations
- [Unicode Character Database 18.0.0: Blocks.txt](https://www.unicode.org/Public/18.0.0/ucd/Blocks.txt) - the Block property
- [Unicode Character Database 18.0.0: DerivedAge.txt](https://www.unicode.org/Public/18.0.0/ucd/DerivedAge.txt) - the version that assigned each code point
- [Unicode Character Database 18.0.0: Scripts.txt and ScriptExtensions.txt](https://www.unicode.org/Public/18.0.0/ucd/ScriptExtensions.txt) - Script and Script_Extensions
- [Unicode Character Database 18.0.0: LineBreak.txt](https://www.unicode.org/Public/18.0.0/ucd/LineBreak.txt) - VT, FF, LS and PS are mandatory breaks (BK), NEL is NL
- [UTS #39 Unicode Security Mechanisms 18.0.0: confusables.txt](https://www.unicode.org/Public/18.0.0/security/confusables.txt) - prototypes of characters confusable with ASCII
- [Unicode Technical Standard #39: Unicode Security Mechanisms (version 18.0.0)](https://www.unicode.org/reports/tr39/) - confusable detection, prototypes and skeletons
- [Unicode Character Database 18.0.0: PropList.txt (Bidi_Control)](https://www.unicode.org/Public/18.0.0/ucd/PropList.txt) - the twelve Bidi_Control characters
- [Unicode Technical Standard #55: Unicode Source Code Handling (version 2)](https://www.unicode.org/reports/tr55/) - line-break, lookalike and bidirectional spoofing in source code
- [Unicode Standard Annex #9: Unicode Bidirectional Algorithm (Unicode 18.0.0)](https://www.unicode.org/reports/tr9/) - embeddings, overrides and isolates, and what closes them
- [Unicode Standard Annex #44: Unicode Character Database (Unicode 18.0.0)](https://www.unicode.org/reports/tr44/) - General_Category values, loose name matching (UAX44-LM2)
- [The Unicode Standard 18.0.0, chapter 4: Character Properties](https://www.unicode.org/versions/Unicode18.0.0/core-spec/chapter-4/) - the Name property and code point labels
- [NVD: CVE-2021-42574 (Trojan Source, bidirectional reordering in source code)](https://nvd.nist.gov/vuln/detail/CVE-2021-42574) - the vulnerability report and the Unicode Consortium's statement in it
- [RFC 3629: UTF-8, a transformation format of ISO 10646](https://www.rfc-editor.org/rfc/rfc3629) - UTF-8 byte sequences; surrogates are not encoded
- [RFC 2781: UTF-16, an encoding of ISO 10646](https://www.rfc-editor.org/rfc/rfc2781) - surrogate pairs
- [RFC 8259: JSON (section 7, strings)](https://www.rfc-editor.org/rfc/rfc8259) - \uXXXX escapes and surrogate pairs
- [ECMA-262: ECMAScript Language Specification (string literals)](https://tc39.es/ecma262/) - \uXXXX and \u{...} escapes
- [The Python Language Reference: Lexical analysis (escape sequences)](https://docs.python.org/3/reference/lexical_analysis.html) - \x, \u and \U escapes
- [ISO/IEC 9899:2011 committee draft N1570 (C11): 6.4.3 universal character names](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) - which code points a universal character name may designate
- [Tcl 8.4 manual: Tcl (backslash substitution)](https://www.tcl-lang.org/man/tcl8.4/TclCmd/Tcl.htm) - \uhhhh, one to four hexadecimal digits
- [WHATWG HTML Living Standard: named character references (entities.json)](https://html.spec.whatwg.org/entities.json) - named references for each code point
- [RFC 3986: URI Generic Syntax (percent-encoding)](https://www.rfc-editor.org/rfc/rfc3986) - unreserved characters and percent-encoded UTF-8

## Related reading

- [ASCII: os 128 códigos, e por que a tabela é desenhada assim](https://ronutz.com/pt-BR/learn/ascii-the-128-codes.md): Sete bits, oito colunas, dezesseis linhas: como a tabela ASCII é organizada, por que maiúsculas e minúsculas estão a um bit de distância, para que os 33 controles foram definidos e quais ainda fazem alguma coisa, por que espaço em branco depende de quem pergunta, e as referências HTML que parecem ASCII e não são.
- [Caracteres escondidos e sósias: o que uma linha de texto pode esconder](https://ronutz.com/pt-BR/learn/hidden-and-lookalike-characters.md): Caracteres de largura zero, controles bidirecionais que reordenam o que você vê (Trojan Source), quebras de linha que o seu analisador não enxerga, letras cirílicas que passam por latinas, e as aspas e traços tipográficos que quebram configurações: o que cada um faz, como os documentos de segurança do Unicode os descrevem e como encontrá-los.
- [Contraste de cor: a aritmética do WCAG e as dez maneiras de o CSS escrever uma cor](https://ronutz.com/pt-BR/learn/colour-contrast-wcag-and-css-color-notations.md): Se um texto pode ser lido sobre o seu fundo é, no WCAG, um único número calculado a partir de duas cores, e o cálculo é curto o bastante para se fazer à mão uma vez. Aqui está a aritmética (luminância relativa, a razão, os limiares de 4.5:1 e 3:1 e de onde vêm), seguida das notações em que o CSS Color Level 4 permite escrever uma cor, de #hex a oklch(), e por que as mais novas tornam um par reprovado mais fácil de corrigir.
- [Mojibake: por que café vira cafÃ©, e como recuperar o texto](https://ronutz.com/pt-BR/learn/mojibake-and-code-pages.md): O texto fica embaralhado quando bytes gravados num charset são lidos em outro. Como surgem os padrões clássicos (UTF-8 lido como windows-1252, arquivos do DOS e do Windows lidos um como o outro, EBCDIC lido como Latin-1), por que o navegador lê Latin-1 como windows-1252, como um único caractere invisível no rótulo do charset embaralha uma página inteira, como desfazer o estrago e quando isso não é possível, e o que a codificação de uma política de WAF do BIG-IP tem a ver com tudo isso.
- [Unicode: pontos de código, planos, nomes e propriedades](https://ronutz.com/pt-BR/learn/unicode-code-points-and-properties.md): O que é um ponto de código, como os 1.114.112 deles se organizam em planos, por que um caractere na tela pode ser vários pontos de código, como o Unicode nomeia e classifica cada caractere, e por que o mesmo emoji mede 1, 2, 4 ou 4 conforme a linguagem que conta.
- [UTF-8, UTF-16 e UTF-32, byte por byte](https://ronutz.com/pt-BR/learn/utf-8-and-utf-16-byte-by-byte.md): Como cada codificação do Unicode distribui um ponto de código em bytes, como reconhecer cada uma num dump hexadecimal, quais sequências de bytes são malformadas e exatamente o que um decodificador substitui por U+FFFD, e o que faz uma marca de ordem de bytes, incluindo o ponto em que um navegador e o padrão Unicode discordam.
