Skip to content

Everything runs in your browser. We never see your text. How we prove it β†’

Character Diff β€” Letter-by-Letter Compare

Paste two strings that ought to be identical. Every differing code point is marked, including the ones you cannot see.

Original
Changed

How character-level comparison works

Two strings can render identically on screen and still be different strings. Cyrillic small letter Π°, code point U+0430, is drawn from the same shape as Latin a at U+0061 in nearly every typeface; a non-breaking space at U+00A0 occupies the same column as an ordinary U+0020; the right single quotation mark U+2019 passes for a typewriter apostrophe until something tries to parse it. This mode compares code point against code point, so each of those becomes a marked substitution instead of an hour lost. Characters with no glyph of their own β€” a trailing space at the end of a token, a tab standing in for four spaces, a CRLF ending meeting a bare LF, a zero-width joiner smuggled in by a chat client β€” are drawn with visible markers rather than quietly normalised away.

Comparison is case-sensitive from the start, because the material that justifies this granularity is case-sensitive too: base64 payloads, bearer tokens, commit SHAs, licence keys. An ignore-case switch exists for the occasions when it is not. Bear in mind that an edit script over individual characters is dense by nature. Feed it two paragraphs and you get a mosaic of marks nobody can read; the sweet spot is one record, a credential, a URL, or a few kilobytes of near-identical text. For anything document-length, Word-Level Diff produces a result you can actually follow, and it will still point you back here once you know which sentence to interrogate.

Credentials never go over the wire

The strings that most need this treatment are precisely the ones that should never be pasted into someone else's form: a production API key checked against the staging vault, a webhook signing secret, a JWT that refuses to validate, a database URL with the password sitting inline. A hosted comparison service would land all of that in a request log with an unknown retention policy. This page has no such path β€” matching runs as local JavaScript and nothing is transmitted. Open your browser's network tab while you use this tool β€” you'll see no request carries your content. Check it for yourself before you trust it.

Where one glyph decides the outcome

  • An engineer staring at a 401 at two in the morning holds the key from the deploy environment against the one in the password manager and discovers the trailing newline a terminal copy quietly appended.
  • A security analyst triaging a phishing report compares the domain in the suspect email with the genuine one and sees at a glance which letter was swapped for its Cyrillic twin.
  • A release manager verifying a download sets the SHA-256 printed on the release page beside the digest shasum produced locally, confirming the mismatch was a truncated paste and not a corrupted artefact.
  • A localisation reviewer approving translated strings catches the em dash a content system converted into an en dash, plus the curly quote that will break a downstream JSON import.
  • A finance operations analyst releasing a payment reconciles the IBAN in the banking portal with the one on the invoice, where a single transposed digit turns into a wire recall and a week of phone calls.

Frequently asked questions

Why do two strings that look the same come back as different?

Almost always an invisible or homoglyph character: a non-breaking space pasted from a web page, a trailing tab, a Windows line ending, a Unicode letter shaped like its ASCII counterpart. The markers in the result show where each one sits, which is generally enough to identify the source β€” a rich-text editor, a PDF copy, or a spreadsheet cell.

How much text can I put through character mode?

Technically the same budget as every tool here: live up to 1 MB combined, a Compare button above that, 50 MB absolute. Practically, character granularity stops being readable somewhere in the low hundreds of kilobytes because the output is mostly highlight. Past roughly thirty thousand lines the engine switches to a line-mode strategy, which defeats the purpose.

Do my keys or tokens leave the browser?

No. There is no request that carries the panes, no account holding a history, and no analytics event containing what you typed. The tool also keeps working with the network disconnected once the page has loaded, which is the simplest demonstration available; the privacy page covers the DevTools version.

Can I make it ignore case or whitespace?

Case can be turned off with a single switch. Whitespace normalisation is available too, though it undoes most of the reason to be on this page β€” if a stray space is what you are hunting, leaving it on will hide the answer. Ignore-case is safe for hex digests, risky for base64.

Is it wise to share a character comparison by link?

The link is safe in transit β€” both inputs live in the fragment after the #, which browsers never send to a server. The risk is the recipient, and their history, and their screenshot. For a live credential, read the difference, fix it, and close the tab rather than generating a link at all.