Coder — Manual
Complete Coder reference: all ten tabs with their options, input and output, JWT signature verification, Data URIs, storage, and the limits.
Back to the overview: Coder · Open the tool: www.jpkc.com/tools/coder/
This manual documents each of the Coder's ten tabs in detail: what it does, which options it offers, what goes in and comes out, the edge cases, and where the limits are. Tab, button, and option names are given as they appear in the interface.
Interface and operation
The tool is a single card with a tab bar at the top: HTML, URL, Base64, JSON, Unicode, Hex, Punycode, Quoted-Printable, JWT, and Data URI. On narrow screens the bar wraps onto several lines.
Switching tabs: click, or use the keyboard — with focus on a tab, the left and right arrow keys move to its neighbor, Home and End jump to the first and last tab. The Coder remembers the last tab you used and also shows it as a fragment in the address bar, so you can link a tab directly, such as https://www.jpkc.com/tools/coder/#jwt or #punycode.
The eight text tabs (HTML through Quoted-Printable) share one workspace:
- A short info line above the editors explains what the current tab does. Below it sit the tab's options as switches or drop-downs (details in the sections below). Changing an option recalculates an existing result immediately, from the text in the Input field; all options are kept in the browser.
- Two editors side by side (stacked on narrow screens): Input on the left, Output on the right. Both are ACE editors with line wrapping; the output is read-only. Encode and Decode write the result to the output — your input stays as it is.
- In the Input header: Recent inputs (clock icon, only visible when you have turned on remembering, see Storage and privacy) and Clear input (X), which empties input and output; Ctrl+Z in the input editor brings the text back.
- In the Output header: Use output as input (double arrow) moves the result into the input — handy for multi-step encodings; Ctrl+Z in the input editor undoes that in one step. Copy output puts the result on the clipboard, Download output saves it as a text file (
<codec>-encoded.txtor<codec>-decoded.txtwith the tab's internal ID and the last chosen direction, Encode or Decode, e.g.base64-encoded.txt, orqp-encoded.txton the Quoted-Printable tab) or, for binary results, as a file. - Below the editors: Encode (shortcut Ctrl+Enter, Cmd+Enter on a Mac) and Decode (Ctrl+Shift+Enter or Cmd+Shift+Enter). The shortcuts work while the cursor is in the input editor.
- The Live (convert while typing) switch converts as you type (after a 200 ms pause) in the direction you used last. It's off by default; from 512 KB of input, live mode pauses with a notice, and you click Encode or Decode yourself.
- A status line below the buttons reports the result and its size ("Encoded · 17 → 28 characters"; when decoding Base64, Hex, and Quoted-Printable, "Decoded · … of UTF-8 text"), or "(nothing to change)" when the text stayed the same. Errors show up there in red, usually with position and cause.
JWT and Data URI have views of their own without Encode/Decode buttons: they evaluate as soon as you paste something.
Architecture: all client-side
Important for understanding and privacy: the server only delivers the HTML page and the ACE editor. The encoding and decoding happen entirely in your browser via JavaScript — Punycode, for example, through a built-in implementation of RFC 3492, JWT signature verification through the browser's Web Crypto API. There is no server-side processing, no API call, and no upload of your input — not on the JWT tab, not when verifying with a secret or key, and not when creating Data URIs. Your tokens, keys, files, and strings stay local.
Storage and privacy
What the Coder keeps in the browser (localStorage) is clearly separated:
- Always stored are settings only: the last tab you used and the options of the text tabs, including the live switch.
- Content is stored only on request. The Remember input and recent entries in this browser switch in the card footer is off by default — and the tool says why: Base64 strings and URLs often contain credentials. Turn it on, and the Coder saves the current input right away and then on every click on Encode or Decode (up to 100,000 characters; it's back in the field on your next visit) and adds it to a list of the last 10 inputs, which you reopen via Recent inputs. Live runs don't end up in the list. Turning remembering off deletes the stored input and hides the list; only Forget stored entries removes the list for good.
- Forget stored entries deletes the stored input and the list of recent inputs, including the lists that older versions of the tool kept for URL, Base64, and JSON.
- JWTs are never stored, not even with remembering turned on; the same goes for secrets and keys on the JWT tab.
HTML — entities
The HTML tab converts characters into HTML entities and back.
- Encode:
&→&,<→<,>→>— always, and in a way that never re-encodes the&of the generated entities. - Option Encode quotes (
"') — on by default: additionally"→"and'→'. You need this when the text ends up in an attribute value (title="…",alt="…"). If it only sits between tags, you can switch it off. - Option Non-ASCII as
ä— additionally writes every character beyond ASCII as a decimal entity:äbecomesä, an emoji😀. Useful for environments that can't cope with UTF-8. - Decode: understands all named entities (
©, ,€…) as well as numeric ones in decimal (€) and hexadecimal form (€) — each with a closing semicolon. Forms without the semicolon, such as©orä, stay unchanged. Decoding happens in one pass:&lt;becomes<, not<— double-encoded text is unwound by exactly one level. Invalid code points turn into the replacement character�; unknown names usually stay as they are. The exception: if an unknown name starts with an entity name that browsers also accept without a semicolon, the browser resolves that start —¬it;becomes¬it;. The output shows the result with HTML syntax highlighting.
The browser itself resolves the named entities; no markup from your input is ever created or executed in the process.
URL — URL encoding
The URL tab percent-encodes a string and decodes it again. The Mode drop-down decides how:
- Component (encodeURIComponent) — the default. For single query values and path segments: everything except letters, digits, and
- _ . ~is encoded, plus! ' ( ) *per RFC 3986. Spaces become%20. - Form (space = +) — like Component, but with
+for spaces, i.e.application/x-www-form-urlencodedstyle as used by HTML forms. On decode,+turns back into a space. - Full URL (encodeURI) — encodes a complete URL and leaves the structural characters
: / ? # & =in place; umlauts and spaces are encoded. On decode, this mode leaves the escapes of reserved characters in place (%2F,%3F,%23,%26,%3D,%3A,%40,%2B,%24,%2C,%3B) — soq=a%26bdoes not becomeq=a&b. To decode everything, choose Component.
On decode, the tool reports broken sequences with their position ("Malformed percent-encoding at position 4") and recognizes when the bytes aren't valid UTF-8 — typical of legacy Latin-1 data such as %E4 for ä.
Query parameters as a table: if the input (on encode) or the result (on decode) contains a query string after ?, or if the text itself looks like name=value&name2=value2, a Query parameters table appears below the output with the name and decoded value of each parameter.
Base64 — text and files
The Base64 tab encodes text to Base64 and decodes Base64 back.
- Encode: converts the text UTF-8 safely, so accents, umlauts, and emoji come through intact.
- Option URL-safe (
-_, no padding) — produces the Base64URL variant (-and_instead of+and/, no=padding) used in JWTs and URLs. - Option Wrap at 76 characters (MIME) — breaks the output after 76 characters, as is customary in e-mail.
- Encode a file… — encodes any file from your computer to Base64, using the options set when the file is read. If you change an option afterwards, the tool recalculates from the text in the Input field and discards the file result (with an empty input, the output stays empty) — for different options, choose the file again. From 25 MB the tool asks first, because that takes time and memory. For a finished
data:URI, use the Data URI tab. - Decode: is forgiving — it accepts both the standard and the URL-safe alphabet, missing padding, spaces and line breaks, and even a complete Data URI (everything up to
;base64,is cut off). Invalid input is reported precisely: an illegal character with its position,=in the middle of the data, or a length that points to truncated data.
Binary results: if the decoded data isn't readable UTF-8 text (an image or a ZIP, say), the output shows a classic hex dump (offset, bytes, ASCII column; the first 64 KB are displayed). Below it you see the size and detected file type, plus a Download decoded.
JSON — escape and unescape a string
The JSON tab handles JSON string values, not whole JSON documents.
- Encode: escapes text so it fits validly between the quotes of a JSON string:
"→\",\→\\, newline →\n, carriage return →\r, tab →\t, plus\b,\f, and every other control character as\u00XX. - Option Add surrounding quotes — wraps the result in quotes right away.
- Option Escape non-ASCII — additionally writes every character from U+007F upward as
\uXXXX(äbecomes\u00e4, emoji become a surrogate pair). That keeps the output pure ASCII. - Decode: resolves all JSON escapes, including
\uXXXX,\b,\f, and\/. The tool detects and strips surrounding quotes itself; raw line breaks and tabs in the input (from multi-line pasted text, for instance) are tolerated. If the input isn't a valid JSON string, the tool reports the approximate position and points to an unescaped"when that's the cause.
To format, validate, or restructure whole JSON documents, use the JSON Editor.
Unicode — escape sequences
The Unicode tab writes characters as escape sequences of various languages. The Format drop-down offers the following formats; in the list, each name comes in parentheses after an example, such as U+00E4 (code points):
| Format | Example for ä |
Use |
|---|---|---|
| JavaScript, JSON, Java (default) | \u00E4 |
characters outside the Basic Multilingual Plane (emoji, for example) as a surrogate pair \uD83D\uDE00 |
| ES2015 | \u{E4} |
modern JavaScript syntax, emoji as \u{1F600} |
| CSS | \E4 |
in CSS strings and content; the trailing space terminates the escape |
| HTML | ä |
hexadecimal numeric entity |
| code points | U+00E4 |
code points for looking things up, space-separated |
- By default only non-ASCII characters are escaped; with the Escape ASCII too option, all others are as well. The code points format lists every character anyway.
- Decode: recognizes the formats automatically and all at once —
\uXXXX(surrogate pairs become one character again),\u{…},\UXXXXXXXX(upper- or lowercase hex digits:\U0001F600and\U0001f600both become 😀),\xXX,&#x…;,&#…;, andU+…. CSS escapes (\E4) are only decoded when CSS is the selected format, because they would otherwise clash with sequences such as\nor\f.
Hex — bytes as hexadecimal
The Hex tab shows text as UTF-8 bytes in hexadecimal — Grüße becomes 47 72 c3 bc c3 9f 65.
- Separator drop-down: none (
4772c3bc…), space (default), or colon (47:72:c3:…). - Option Uppercase — capital letters (
C3 BCinstead ofc3 bc). - Encode a file… — as on the Base64 tab, just with hex output.
- Decode: ignores spaces, line breaks, colons, commas, hyphens, and the prefixes
0xand\x. So you can paste hex straight from debuggers, packet captures, or C source. Invalid characters or an odd number of digits are reported as errors. If the bytes don't form text, the binary view with hex dump and download takes over (see Base64).
Punycode — internationalized domains
The Punycode tab translates internationalized domain names (IDN) between their Unicode form and the ASCII form used in DNS: bücher.de ↔ xn--bcher-kva.de.
- Input is processed line by line; each line may be a domain, a full URL, or an e-mail address. Only the host is converted — scheme, path, query, port, and the part before the
@remain unchanged. - Encode: every label (the part between two dots) containing non-ASCII characters is normalized (Unicode NFC), lowercased, and encoded as
xn--…; pure ASCII labels stay as they are. - Decode: converts every label with the
xn--prefix back. Invalid Punycode is reported along with the affected label.
The implementation follows the Punycode algorithm from RFC 3492. It doesn't replicate the extra character mapping browsers apply before encoding (UTS 46), so in special cases such as ß the result can differ from what the browser's address bar shows.
Quoted-Printable — e-mail encoding
The Quoted-Printable tab implements the encoding from e-mail source per RFC 2045, based on UTF-8.
- Encode: printable ASCII characters stay;
=and every other byte (umlauts, control characters) become=XX—üturns into=C3=BC. Spaces and tabs at the end of a line are encoded too. Lines are limited to 76 characters with a soft line break (=at the end of the line); your own line breaks are preserved. - Decode: removes the soft line breaks and turns
=XXsequences back into bytes. The result appears as text or — if it isn't UTF-8 text — in the binary view.
JWT — decode and verify the signature
The JWT tab takes a JSON Web Token apart, explains its contents, and verifies the signature on request. There's no Decode button: the tool evaluates as soon as you paste or type the token into the Token field.
Input: a leading Bearer (copied from an Authorization header, say) and spaces or line breaks inside the token are ignored.
Format checks:
- A token with five parts is recognized as an encrypted token (JWE); the tool shows only its header — the payload can only be read with the recipient's private key.
- If the token doesn't have exactly three parts, the tool reports "Not a JWT: expected 3 parts separated by dots, found …".
- Header and payload must be valid Base64URL with UTF-8, the header a JSON object. A payload that isn't JSON is shown as text (notice "Payload is not JSON — shown as text").
- On an error, the previous result disappears — an old token never lingers on screen.
Display:
- Header and Payload as indented JSON, each with its own Copy button.
- Claims — a table listing every payload field, its value, and a plain-language meaning for the common claims (
iss,sub,aud,exp,nbf,iat,jti,auth_time,azp,nonce,scope/scp,roles,email,name,sid, and more). Timestamps (exp,nbf,iat,auth_time,updated_at) also appear as local date, relative time, and ISO timestamp. - Signature with the algorithm from the header and the signature as a raw string.
Status badges above the result, computed from the payload fields and the current time:
- "Expired …" (with relative time), "Not valid yet — becomes valid …" (
nbflies in the future), "Within its validity period — expires …", or "No expiry (exp) set". "exp" is not a numberif the expiry isn't a numeric value.- "Unsigned token (alg: …) — never accept it" if the header says
alg: noneor the signature is missing; the parentheses show the algorithm from the header (ormissingif there is noalg).
Verifying the signature: in the signature section, enter the key and click Verify signature. The field and options adapt to the token's algorithm:
- HMAC (HS256, HS384, HS512): a Secret field for the shared secret. With the Secret is Base64-encoded switch, the secret is Base64- or Base64URL-decoded first — needed when your server manages the secret as a Base64 string. Instead of a secret, the field also accepts a JWK with
"kty": "oct"or a JWKS containing such keys. If the content starts with{, the tool always reads it as a JWK; a secret that itself starts with{therefore needs to be Base64-encoded first, with Secret is Base64-encoded switched on. - RSA (RS256/384/512), RSA-PSS (PS256/384/512), ECDSA (ES256/384/512), and EdDSA (Ed25519): a Public key field for a public key as PEM (
-----BEGIN PUBLIC KEY-----), as a JWK, or as a JWKS (a key set with"keys": […]). From a JWKS, the tool picks the key matching thekidin the token header, or the only key if there's just one. - Result: "✓ Signature verified — the token was signed with this key." or "✗ Signature does NOT match this key/secret."
Safeguards and limits of the check:
- Algorithm confusion is refused: if a token claims HMAC (
HS…) but you enter a public key or a certificate, the tool refuses to verify and tells you to treat the token as forged. The background is a well-known attack in which the public key is abused as the HMAC secret. - A JWK must match the algorithm (
ktyoct,RSA,EC, orOKP), and analgset in the JWK must match the token's. - Certificates (
BEGIN CERTIFICATE) and RSA keys in PKCS#1 format (BEGIN RSA PUBLIC KEY) can't be imported by the browser; the tool then gives you the matchingopensslcommand to convert them toBEGIN PUBLIC KEY. For a PKCS#1 key, the PKI Viewer is an alternative: it outputs the key asBEGIN PUBLIC KEY(Show PEM, Copy PEM, download aspublic-key.pem). - Ed25519 requires a current browser. Other algorithms are reported as unsupported; with
alg: nonethere's nothing to verify. - Only the signature is checked. Whether issuer (
iss) and audience (aud) are right is not assessed; the validity badges are no substitute for server-side checks. The Coder does not create tokens.
Data URI — file to Data URI and back
The Data URI tab has two halves.
File → Data URI turns any file into a Base64-encoded data: URI:
- Drag a file onto the Drop a file here or choose one area, or pick it with the file dialog.
- The browser reads it locally; a progress bar shows the read status. For files over 10 MB, the tool asks first and states the expected size of the URI — Data URIs that large are impractical and can freeze the page.
- An info line shows file name, MIME type (or "unknown type" if the browser doesn't know one), file size, and the size of the Data URI. From about 32 KB, the tool suggests serving a normal file instead.
- Output as sets the output format: Data URI (
data:<mimetype>;base64,…), CSS background-image (background-image: url("…");), HTML<img>(with the file name asalttext), Markdown image (), or Base64 only (just the encoded data). Copy puts the result on the clipboard; the output field is read-only. - Images get a preview.
Data URI → File goes the other way: paste a data: URI, and the tool decodes it right away.
- Both Base64 and percent-encoded Data URIs are accepted; if the MIME type is missing,
text/plainapplies. - You see MIME type, size, and encoding, plus a Download file.
button — the extension comes from the first bytes of the data or, if those don't give anything away, from the MIME type. - There's a preview for real raster images (PNG, JPEG, GIF, WebP, ICO) and for text (the first 5,000 characters). SVG is deliberately not displayed because it can contain scripts — download it instead. For the same reason, the download always saves the data with a neutral file type.
Base64 grows data by about a third, so Data URIs pay off mostly for small assets such as icons; in neither direction is the file uploaded.
Limits — at a glance
- HTML decode unwinds exactly one level of encoding; unknown entity names and entities without a closing semicolon stay as they are.
- URL encodes differently depending on the mode — Component or Form for query values, Full URL for whole addresses; on decode, Full URL leaves escapes of reserved characters (
%2F,%26…) in place. Non-UTF-8 legacy data (Latin-1) can't be decoded. - JSON handles string values, not whole documents.
- Unicode decodes CSS escapes only when CSS is the selected format.
\uand\Uare case-sensitive, as in C and Python:\uexpects exactly four hex digits,\Uexactly eight. - Punycode implements RFC 3492 but no UTS 46 mapping; special cases such as
ßcan differ from the browser. - Binary results are shown as a hex dump only up to 64 KB; the download contains everything. File encoding asks for confirmation from 25 MB, Data URIs from 10 MB; an encoded file is not recalculated when you change an option.
- Live mode pauses from 512 KB of input.
- JWT checks only the signature, not
iss/aud; no token creation, no JWE decryption, no certificates or PKCS#1 keys. - Data URI relies on the browser-reported MIME type when encoding; SVG gets no preview on the way back.
For the big picture and the audiences, see the overview; for concrete workflows, the examples. You can try everything right in the tool.