Escape / Unescape Unicode
Converta texto para escapes \uXXXX ou \u{XXXXX} e vice-versa. Lida com pares surrogate para emoji.
Unicode Escape / Unescape
Runs entirely in your browser. Your input never leaves your device.
What next?
How it works
O que é o escape de Unicode
O escape de Unicode converte caracteres para sua representação de sequência de escape \uXXXX (ou \u{XXXXX}) — e vice-versa. O caractere é se torna é; o emoji 👀 se torna \u{1f440} no modo ES6 ou o par substituto 👀 no modo JSON.
Isso não é codificação para compressão ou segurança. É uma representação segura para texto que permite incorporar qualquer caractere Unicode em um contexto que só aceita ASCII — valores de strings JSON, arquivos-fonte JavaScript, literais de string em C, arquivos .properties Java e contextos similares.
As duas sintaxes de escape
\uXXXX — quatro dígitos hexadecimais (somente BMP)
A sintaxe de escape Unicode original, definida na especificação ECMAScript 1 (1997) e exigida pela especificação JSON (RFC 8259 §7). Funciona para pontos de código U+0000 a U+FFFF — o Plano Multilíngue Básico (BMP). Para esses 65.536 caracteres, é e é são exatamente equivalentes em qualquer parser em conformidade.
\u{XXXXX} — dígitos hex variáveis entre chaves (Unicode completo)
Introduzida no ES6 (ECMAScript 2015). Suporta o intervalo Unicode completo U+000000 a U+10FFFF. Esta é a forma correta de escapar caracteres do plano astral — pontos de código acima de U+FFFF que incluem a maioria dos emoji, escritas históricas e símbolos matemáticos. \u{1f600} é mais limpo e inequívoco; a sintaxe de chaves também permite omitir zeros iniciais.
JSON não suporta \u{} — parsers JSON esperam exatamente quatro dígitos hex após \u. Para incorporar um ponto de código do plano astral em JSON, você deve usar pares substitutos.
O plano astral e os pares substitutos
O Plano Multilíngue Básico do Unicode contém os pontos de código U+0000–U+FFFF. Tudo acima — chamado de planos astrais ou caracteres suplementares — requer uma estratégia diferente em sistemas construídos sobre UTF-16.
Strings JavaScript são internamente UTF-16. Para representar um ponto de código acima de U+FFFF em UTF-16, dois code units de 16 bits chamados par substituto são usados: um substituto alto (U+D800–U+DBFF) seguido de um substituto baixo (U+DC00–U+DFFF). A fórmula:
codepoint = 0x10000 + (high - 0xD800) × 0x400 + (low - 0xDC00)
O emoji 😀 (U+1F600) se torna o par 😀. Em JSON, essa é a única forma de representá-lo pois o escape \u do JSON só aceita quatro dígitos hex. Em JavaScript ES6, você pode usar \u{1F600} diretamente.
A armadilha: como um par substituto são duas sequências \u, operações de string ingênuas que trabalham caractere por caractere se quebram. "😀".length retorna 2 em JavaScript, não 1. "😀"[0] retorna o substituto alto solto \uD83D, não o emoji. Dividir por clusters de grafemas requer [...str] (spread) ou Intl.Segmenter no ES2022+.
Modo JSON vs modo ES6 vs modo "all"
Modo JSON — escapa todo caractere não ASCII usando apenas \uXXXX, com pares substitutos para pontos de código acima de U+FFFF. A saída é sempre válida dentro de um literal de string JSON.
Modo ES6 — usa \u{XXXXX} para caracteres astrais e \uXXXX para caracteres BMP. Produz saída mais curta e legível para strings com muitos emoji. Válido apenas em contextos JavaScript ES6+ — não em JSON, não em ambientes ES5 mais antigos.
Modo all — escapa todo caractere, incluindo ASCII. Útil quando você precisa de uma representação puramente ASCII de uma string sem nenhum Unicode bruto — para incorporar em strings C, arquivos-fonte Python ou depurar caractere por caractere.
String.fromCodePoint vs String.fromCharCode
Essas duas funções JavaScript revelam diretamente a complexidade do par substituto:
String.fromCharCode(0x1F600) // "?" — errado, trunca para U+F600
String.fromCodePoint(0x1F600) // "😀" — correto
String.fromCharCode(0xD83D, 0xDE00) // "😀" — correto via par substituto
String.fromCodePoint(0x1F600) // "😀" — correto via ponto de código
fromCharCode é anterior aos planos astrais do Unicode e opera em code units UTF-16 brutos. Se você passar um ponto de código acima de 0xFFFF, ele trunca silenciosamente. fromCodePoint (ES6) lida com o intervalo completo. Ao fazer unescape de \u{1F600}, use sempre fromCodePoint.
Quando JSON obriga a escapar?
A especificação JSON (RFC 8259) exige que os caracteres de controle U+0000–U+001F sejam escapados. Todos os outros caracteres podem ser incluídos como UTF-8 bruto, mas muitos serializadores escapam todo o intervalo não ASCII por segurança. Se você receber um payload JSON e ver à onde esperava à, o JSON foi produzido com uma configuração de "escapar completamente os não ASCII". Ambas as representações são idênticas para um parser JSON em conformidade.
Literais de template e quando você não precisa de escape
Em literais de template ES6 e literais de string JavaScript modernos, você pode incorporar Unicode diretamente:
const saudacao = `Olá, Brasil!`; // sem necessidade de escape
const emoji = "😀"; // funciona em JS moderno
const escaped = "\u{1F600}"; // idêntico ao anterior
Você precisa de escape quando: a string será incorporada em JSON programaticamente, o arquivo deve ser somente ASCII (toolchains antigos, alguns arquivos .properties), você está depurando um caractere e quer ver seu ponto de código explicitamente, ou está passando a string por um canal que corrompe Unicode bruto.
Privacidade
Todo o processamento roda no seu navegador. Seu texto nunca é enviado a um servidor.
Ferramentas relacionadas
- URL Encode/Decode — codificação percentual para componentes URI, um esquema de escape diferente.
- HTML Entity Encode/Decode —
&,ée referências de caracteres HTML similares.
FAQ
Por que meu emoji aparece como duas sequências \u no modo JSON?
Porque o escape \u do JSON só aceita exatamente quatro dígitos hexadecimais, cobrindo pontos de código até U+FFFF. Emoji vivem nos planos astrais (acima de U+FFFF) e devem ser representados como pares substitutos UTF-16 — duas sequências \u consecutivas. Por exemplo, 😀 (U+1F600) se torna 😀. Use o modo ES6 para obter a forma mais limpa \u{1F600}, mas note que parsers JSON não aceitam a sintaxe de chaves.
Qual é a diferença entre \uXXXX e \u{XXXXX}?
\uXXXX é a sintaxe original de quatro dígitos hex do ECMAScript 1 (1997) e da especificação JSON (RFC 8259). Cobre apenas o Plano Multilíngue Básico (U+0000–U+FFFF). \u{XXXXX} é a sintaxe de chaves do ES6 que aceita qualquer número de dígitos hex e cobre o intervalo Unicode completo até U+10FFFF. A forma de chaves é válida em JavaScript ES6+ e muitas linguagens modernas, mas não em JSON — a especificação JSON nunca foi atualizada para incluí-la.
Por que "😀".length retorna 2 em JavaScript?
Strings JavaScript são internamente UTF-16. Pontos de código acima de U+FFFF são armazenados como dois code units de 16 bits (um par substituto), então String.prototype.length conta code units, não caracteres. Use [...str].length (o spread usa o iterador de string, que reconhece pontos de código) ou Array.from(str).length para obter a contagem correta de caracteres. Intl.Segmenter fornece contagens de clusters de grafemas, que é o que os usuários percebem como "número de caracteres".
Quando realmente preciso escapar Unicode em JavaScript?
Raramente em código moderno. Arquivos-fonte ES6+ salvos como UTF-8 podem conter caracteres Unicode diretamente. Você precisa de escapes \u quando: (1) o arquivo deve ser somente ASCII para um toolchain legado, (2) você está construindo uma string JSON programaticamente e precisa incorporar conteúdo não ASCII de forma segura, (3) o ambiente de destino tem suporte Unicode incompleto, ou (4) você está depurando um ponto de código específico e quer torná-lo explícito no código-fonte.
JSON exige que caracteres não ASCII sejam escapados?
Não — o RFC 8259 permite que qualquer caractere Unicode codificado como UTF-8 apareça sem escape em uma string JSON, exceto caracteres de controle (U+0000–U+001F). Muitos serializadores JSON escapam todo o intervalo não ASCII de qualquer forma, por segurança em transportes somente ASCII ou para evitar riscos de injeção HTML. Ambas as representações são idênticas para um parser em conformidade.
O que é String.fromCodePoint e por que devo preferir ao invés de String.fromCharCode?
String.fromCharCode (ES1) opera em code units UTF-16 brutos e trunca silenciosamente valores acima de 0xFFFF. String.fromCodePoint (ES6) lida com o intervalo Unicode completo — passe 0x1F600 e você obtém 😀, não lixo. Use sempre fromCodePoint ao converter um número de ponto de código em um caractere, especialmente se o ponto de código pode estar no plano astral.
O que o modo "all" faz que os modos JSON e ES6 não fazem?
O modo all escapa todo caractere — incluindo letras e dígitos ASCII comuns — não apenas os não ASCII ou não imprimíveis. O resultado é uma string puramente ASCII onde cada caractere é representado como \uXXXX. Útil para incorporar em literais de string C que devem ser somente ASCII, certos formatos de arquivos .properties (a ferramenta native2ascii do Java produz isso), ou para depurar sequências de caracteres onde você quer ver cada ponto de código explicitamente.
Dividir uma string em um emoji pode quebrá-la?
Sim. Como muitos emoji são pares substitutos (dois code units UTF-16), operações que trabalham no nível de code unit — str[i], str.substring(), str.split('') — podem cortar entre as duas metades de um par, produzindo substitutos soltos e saída corrompida. Alternativas seguras: o operador spread [...str] itera por ponto de código, e Intl.Segmenter itera por cluster de grafemas (levando em conta modificadores de emoji e sequências ZWJ como emoji de família compostos de múltiplos pontos de código).