URL encoding by language, compared side by side.

Type any string and see exactly what 14 URL-encoding functions in JavaScript, Python, PHP, Java, Go, Ruby and C# produce — with every difference from strict RFC 3986 highlighted. Each one was checked against the real language runtime.

Encoding Comparator

Highlighted characters are encoded differently from strict RFC 3986 (Python quote(s, safe=""), which keeps only A–Z a–z 0–9 - . _ ~). Hover one to see the strict form.

Every punctuation character, every function.

Green = left as-is. Amber = space written as +. Everything else shows the encoded form. Letters and digits are never encoded by any of these, so they’re left out.

Why the same string encodes differently

There isn’t one “URL encoding”. There are two standards and many interpretations of them:

  • RFC 3986 percent-encoding — for URL paths and general use. A space is %20, and only A–Z a–z 0–9 - . _ ~ are guaranteed safe. PHP rawurlencode, Ruby ERB::Util.url_encode, C# Uri.EscapeDataString and Python quote(s, safe="") follow it exactly.
  • HTML form encoding (application/x-www-form-urlencoded, defined by the WHATWG URL Standard) — for query strings and form bodies. A space is +. PHP urlencode, Java URLEncoder, Go QueryEscape, Python quote_plus, Ruby encode_www_form_component and JavaScript’s URLSearchParams use it — but they still disagree on ~ and *.

The differences that cause bugs

  • Space as + or %20. A + in a path is a literal plus, so form-encoded values pasted into a path break. Decode with the matching rule.
  • Python’s quote() keeps /. Its default safe="/" is right for paths and wrong for a single value — a/b as a parameter stays a/b.
  • ~ is encoded by PHP urlencode, Java and Ruby’s form encoder but not by anything else, so signatures computed over the encoded string (OAuth 1.0a, AWS SigV4) fail when two systems disagree.
  • encodeURIComponent leaves ! ' ( ) * alone. RFC 3986 allows that, but strict servers and signature schemes expect them encoded.
  • Go PathEscape keeps $ & + : = @ but encodes ; and , — different again from every other path encoder here.

How this was tested

Each function was run in its real runtime — Python 3.13, PHP 8.3, Java 21, Go 1.24, Ruby 3.3 and Node 22 — on all 128 ASCII characters plus multi-byte UTF-8 samples (é, 你好, 😀, a mixed URL and control characters): 1,742 comparisons, all identical to what this page produces. C# Uri.EscapeDataString couldn’t be run here; its row follows Microsoft’s documentation, which says it escapes everything except the RFC 3986 unreserved characters. All functions are given UTF-8 input, and hex digits are uppercase in every case.

For worked code in each language, see URL encoding by language.

Sources & standards

Common questions.

Its safe parameter defaults to "/", so slashes are kept for use in paths. Call quote(value, safe="") when encoding a single parameter value.

%20 under RFC 3986 (paths, and anything that isn’t form data); + under HTML form encoding (query strings built by forms, URLSearchParams, PHP urlencode, Java URLEncoder, Go QueryEscape). Both are valid in a query string; only %20 means a space in a path.

None exactly. encodeURIComponent also leaves ! ' ( ) * unencoded. PHP rawurlencode, Ruby ERB::Util.url_encode, C# Uri.EscapeDataString and Python quote(s, safe="") encode those five and otherwise agree with it.

Older form-encoding rules didn’t treat ~ as safe. PHP urlencode, Java URLEncoder and Ruby URI.encode_www_form_component still encode it; RFC 3986 says it never needs encoding.

Yes for JavaScript, Python, PHP, Java, Go and Ruby: every function was run in its own runtime on all 128 ASCII characters plus Unicode samples, and this page matched all 1,742 results. C# follows Microsoft’s documentation because no .NET runtime was available for testing.

More from the toolkit.

About this page. Written and maintained by Sri Murugan Systems, the developer of urlencodedecode.com. Everything on this page runs in your browser; nothing you paste is uploaded or logged.