URL Encode e Decode online
URL encode — ou percent-encoding — troca os caracteres que têm significado num endereço, ou que não cabem nele, por % seguido do valor do byte em hexadecimal: o espaço vira %20, o & vira %26 e o ç vira %C3%A7. URL decode faz o caminho inverso. Esta ferramenta faz os dois no seu navegador: a URL que você cola não é enviada para nenhum servidor.
Conversor
0 caracteres
0 caracteres
O que é URL encode (percent-encoding)
Uma URL só aceita um conjunto restrito de caracteres, e alguns deles têm função estrutural: o ? começa a query string, o & separa parâmetros, o / separa segmentos de caminho. Quando um desses caracteres precisa aparecer como dado, e não como estrutura, ele tem de ser substituído — e é isso que o percent-encoding faz.
A substituição é sempre % seguido de dois dígitos hexadecimais que representam o byte, não o caractere. Essa distinção explica o que mais confunde: em UTF-8 o ç ocupa dois bytes, então vira %C3%A7; o € ocupa três e vira %E2%82%AC.
Os três modos, e como escolher
Esta é a decisão que importa, e ela não dá erro quando você acerta nem quando erra — só produz uma URL que não funciona. Os três modos existem porque três especificações diferentes falam de percent-encoding.
| Modo | O que preserva | Espaço | Quando usar |
|---|---|---|---|
| Componente | só letras, dígitos e -_.~!'()* | %20 | Um valor dentro de um parâmetro. É o caso mais comum, e o padrão da ferramenta. |
| URL inteira | a estrutura: : / ? # [ ] @ & = + $ , ; | %20 | Um endereço já montado, que você só quer tornar válido. |
| Formulário | o mesmo do componente | + | Corpo de POST de formulário, e APIs que esperam o espaço como +. |
A regra prática para escolher entre os dois primeiros: se o texto contém uma barra que precisa continuar sendo barra, é URL inteira; se a barra faz parte do dado, é componente.
Tabela de caracteres
| Caractere | Componente | Formulário | Por que importa |
|---|---|---|---|
| espaço | %20 | + | O caso mais comum, e o único em que os dois modos discordam. Errar aqui é o bug clássico de query string. |
| & | %26 | %26 | Separa parâmetros. Um & não codificado dentro de um valor parte o parâmetro em dois. |
| = | %3D | %3D | Separa nome e valor. Dentro do valor precisa ser codificado. |
| ? | %3F | %3F | Começa a query string. Um segundo ? não codificado confunde parsers antigos. |
| # | %23 | %23 | Começa o fragmento — e tudo depois dele NUNCA é enviado ao servidor. É a falha mais silenciosa da lista. |
| / | %2F | %2F | Separa segmentos de caminho. Num valor, um / não codificado vira caminho. |
| + | %2B | %2B | No modo formulário, um + não codificado é lido como espaço na volta. |
| % | %25 | %25 | Inicia a própria sequência de escape. Um % literal não codificado quebra a decodificação inteira. |
| : | %3A | %3A | Separa esquema e porta. |
| @ | %40 | %40 | Separa credenciais do host. Comum em e-mail dentro de parâmetro. |
| " | %22 | %22 | Aspas em JSON dentro de parâmetro. |
| < | %3C | %3C | Reduz o risco de o valor ser interpretado como marcação se for refletido numa página. |
| > | %3E | %3E | Idem. |
| ; | %3B | %3B | Separador de parâmetro em convenções antigas. |
| , | %2C | %2C | Separador de lista em algumas APIs. |
| á | %C3%A1 | %C3%A1 | Acento em UTF-8 vira DOIS bytes, logo dois grupos %XX. Não é erro. |
| ç | %C3%A7 | %C3%A7 | Idem — e é o que aparece quando um sistema decodifica com a codificação errada. |
| € | %E2%82%AC | %E2%82%AC | Três bytes em UTF-8, três grupos. |
| - _ . ~ | não muda | ~ vira %7E no .NET | A RFC 3986 chama estes de NÃO RESERVADOS: não precisam de escape. Ver a observação sobre WebUtility.UrlEncode. |
| ! ' ( ) * | não muda no JS | codificados por Uri.EscapeDataString | Zona cinzenta: a RFC os chama de sub-delimitadores. JavaScript não codifica, .NET codifica. |
Exemplos de antes e depois
Valor com espaço e acento indo para um parâmetro (componente)
Entrada: São Paulo & Região
Resultado: S%C3%A3o%20Paulo%20%26%20Regi%C3%A3o
?cidade=S%C3%A3o%20Paulo%20%26%20Regi%C3%A3oA mesma coisa em corpo de formulário (formulário)
Entrada: São Paulo & Região
Resultado: S%C3%A3o+Paulo+%26+Regi%C3%A3oURL inteira, já montada, com espaço no caminho (URL inteira)
Entrada: https://exemplo.com/relatório final.pdf?q=café
Resultado: https://exemplo.com/relat%C3%B3rio%20final.pdf?q=caf%C3%A9A MESMA URL no modo componente — o que não se quer
Entrada: https://exemplo.com/a?q=1
Resultado: https%3A%2F%2Fexemplo.com%2Fa%3Fq%3D1
Vira um texto, não um endereço. É o erro de escolher o modo errado.Decodificando um link colado de um log (componente)
Entrada: %2Fbusca%3Ftermo%3Dc%C3%B3digo%20limpo
Resultado: /busca?termo=código limpoComo fazer URL encode e decode em C#
São duas APIs, e a escolha entre elas é a mesma escolha de modo da tabela acima. Os valores abaixo foram conferidos executando o código:
using System;
using System.Net;
// O caminho certo para um VALOR: percent-encoding puro, espaço vira %20
Uri.EscapeDataString("a b"); // a%20b
Uri.EscapeDataString("olá"); // ol%C3%A1
Uri.EscapeDataString("a+b"); // a%2Bb
Uri.EscapeDataString("-_.~"); // -_.~ (não reservados, preservados)
Uri.EscapeDataString("!'()*"); // %21%27%28%29%2A
// O caminho de FORMULÁRIO: espaço vira +
WebUtility.UrlEncode("a b"); // a+b
WebUtility.UrlEncode("-_.~"); // -_.%7E (o til é codificado — ver abaixo)
// Na volta, a diferença aparece de novo
Uri.UnescapeDataString("a+b"); // a+b (o + continua +)
WebUtility.UrlDecode("a+b"); // a b (o + virou espaço)Duas observações que costumam custar tempo. A primeira: Uri.EscapeUriString está obsoleta desde o .NET 6 justamente porque não conseguia distinguir estrutura de dado — se você a encontrar em código antigo, ela é candidata a defeito, não a referência. A segunda: WebUtility.UrlEncode codifica o til como %7E, embora a RFC 3986 o liste como não reservado. Não quebra nada, porque %7E volta a ser ~ na decodificação — mas as duas saídas diferem byte a byte, o que importa quando a URL entra numa assinatura ou num hash.
Montando query string sem errar o escape
Em ASP.NET Core, o caminho seguro é não concatenar à mão: deixe cada valor ser codificado sozinho, no momento em que entra.
using Microsoft.AspNetCore.WebUtilities;
var url = QueryHelpers.AddQueryString("https://api.exemplo.com/busca",
new Dictionary<string, string?>
{
["termo"] = "código limpo & testes",
["pagina"] = "2"
});
// https://api.exemplo.com/busca?termo=c%C3%B3digo%20limpo%20%26%20testes&pagina=2As armadilhas que aparecem em produção
O # não codificado. Tudo que vem depois de um # numa URL é o fragmento, e o fragmento nunca é enviado ao servidor. Um valor com # dentro, sem codificar, chega truncado no ponto exato do # — e o log do servidor mostra a URL curta, sem indício nenhum de que houve corte.
Codificar duas vezes. Aplicar o encode sobre um valor já codificado transforma %20 em %2520, porque o % também é codificado. O sintoma é um valor que chega com %20 literal dentro, visível na tela, em vez do espaço.
Codificar a URL inteira no modo componente. Vira um texto, não um endereço — as barras e os dois-pontos somem. Codifique os valores, no momento em que os insere, e nunca o endereço pronto.
Trocar os modos entre ida e volta. Um valor codificado como formulário e decodificado como componente devolve + onde havia espaço. É a mesma URL, os dois lados "funcionando", e o dado corrompido no meio.
Perguntas frequentes
Os dados que eu colo aqui são enviados para algum servidor?
Não. A URL que você cola nesta ferramenta não é enviada a lugar nenhum: a conversão acontece inteiramente no seu navegador, em JavaScript. Dá para conferir abrindo o DevTools na aba Network e clicando em converter — nenhuma requisição nova parte. Isso importa mais aqui do que numa ferramenta comum, porque URL costuma carregar token, chave de API e identificador de sessão dentro da query string.
Qual a diferença entre %20 e + para o espaço?
Os dois representam o espaço, mas em especificações diferentes. O %20 é o percent-encoding da RFC 3986 e vale em qualquer parte de uma URL. O + só significa espaço dentro do formato application/x-www-form-urlencoded, que é o de corpo de formulário HTML e, por herança, o de muita query string. Fora desse contexto o + é um caractere literal — e é por isso que um valor codificado como formulário e decodificado como componente devolve o + no lugar do espaço.
Qual modo eu devo usar?
Use o modo componente quando estiver codificando UM VALOR que vai dentro de um parâmetro, que é o caso mais comum. Use o modo URL inteira quando já tiver o endereço montado e só quiser torná-lo válido, preservando as barras, os dois-pontos e o ponto de interrogação. Use o modo formulário quando o valor for para o corpo de um POST de formulário ou para uma API que espera o espaço como +. Na dúvida entre os dois primeiros: se o texto que você vai codificar contém uma barra que precisa continuar sendo barra, é URL inteira; se a barra é parte do dado, é componente.
Por que o acento vira dois grupos de porcentagem, como %C3%A7?
Porque o percent-encoding codifica BYTES, e não caracteres. Em UTF-8, o ç ocupa dois bytes — 0xC3 e 0xA7 — então ele vira %C3%A7. Um caractere de três bytes, como o €, vira três grupos. Se você vir %E7 sozinho para um ç, o texto foi codificado em ISO-8859-1 ou windows-1252, e não em UTF-8: é aí que nascem os acentos quebrados.
Qual a diferença entre URL encode e HTML encode?
O URL encode protege caracteres que têm significado num ENDEREÇO, trocando-os por percent-encoding: o espaço vira %20 e o & vira %26. O HTML encode protege caracteres que têm significado na MARCAÇÃO, trocando-os por entidades: o & vira & e o < vira <. São tabelas diferentes para contextos diferentes, e usar uma no lugar da outra não dá erro — apenas produz um valor que não funciona.
Como fazer URL encode em C#?
Use Uri.EscapeDataString para codificar um valor: ela faz percent-encoding puro, com o espaço virando %20, e é a escolha certa para montar query string ou segmento de caminho. Use WebUtility.UrlEncode, do namespace System.Net, quando precisar do formato de formulário, em que o espaço vira +. Evite Uri.EscapeUriString: ela está marcada como obsoleta desde o .NET 6 porque não conseguia distinguir o que era estrutura do que era dado, e produzia resultado errado em ambos os casos.
Por que WebUtility.UrlEncode transforma o til em %7E?
É uma divergência conhecida entre a implementação e a especificação. A RFC 3986 lista o til entre os caracteres NÃO RESERVADOS, que não precisam de escape — e Uri.EscapeDataString respeita isso, deixando o ~ intacto. Já WebUtility.UrlEncode codifica o til como %7E. Nenhum dos dois quebra na prática, porque %7E é decodificado de volta para ~, mas as duas saídas são diferentes byte a byte, o que importa quando a URL entra numa assinatura ou num cálculo de hash.
Preciso codificar a URL inteira antes de fazer uma requisição?
Não, e fazer isso costuma quebrar a requisição. Codifique apenas os VALORES que você insere na URL, no momento em que os insere. Codificar o endereço já montado no modo componente transforma as barras em %2F e os dois-pontos em %3A, e o resultado deixa de ser um endereço. Em ASP.NET Core, o caminho seguro é montar a query string com QueryHelpers.AddQueryString, que codifica cada valor sozinho.
Outras ferramentas
Precisa do outro escape? O HTML Encode e Decode trata dos caracteres que têm significado na marcação — &, <, > e as aspas —, que é um problema diferente deste. Todas as ferramentas estão em ferramentas para desenvolvedor.
Receba os próximos artigos
Conteúdo técnico de .NET direto no seu e-mail. Sem spam, e você sai quando quiser.