99tools

Unicode Character Inspector

runs in your browser

See every character in a string: code point, name, script, UTF-8 bytes and escapes. Finds the zero-width spaces and lookalikes that break a comparison.

Paste the text that will not match. Every character is listed with what it actually is, and anything you cannot see is marked.

Text

about this tool

Two strings look identical. The comparison says they are different. This is the tool for that half hour.

The answer is nearly always a character you cannot see. Paste the string and every character is listed with what it actually is — code point, name, script, the bytes it becomes — and anything invisible or misleading is marked.

The usual suspects

Zero-width space (U+200B) has no width at all. It travels through copy and paste from chat clients, wikis and web pages, and lands in the middle of a password or an API key where nothing will ever show it to you.

Non-breaking space (U+00A0) is what a word processor inserts when you press space in the wrong place. It looks exactly like a space, is not one, and breaks every split(' ') it meets.

Cyrillic and Greek lookalikes. а е о р с are Cyrillic letters drawn identically to their Latin cousins. This is how homograph domains work, and how an identifier copied out of a slide deck stops resolving.

Soft hyphen (U+00AD) is added by PDFs for line breaking and stays in the text you copy out.

Fullwidth forms. Test is four characters from the fullwidth block, not the four ASCII letters they are drawn as. They come from East Asian input methods and from text pasted out of spreadsheets, and a filename or a column header carrying them matches nothing.

Direction overrides (U+202E and friends) change the order text renders in without changing how it is stored — a file called harmlessfdp.txt can display as harmlesstxt.pdf. They are flagged on their own line because they are used on purpose to deceive.

Three lengths, not one

"Length" means three different things, and the gap between them is usually the thing you are looking for. For the family emoji 👨‍👩‍👧:

  • 1 character — what a reader counts
  • 5 code points — what Unicode counts, and what this tool lists
  • 8 UTF-16 units — what JavaScript's .length returns
  • 18 bytes — what goes over the wire as UTF-8

A database column of VARCHAR(10) and an input with maxlength="10" are not counting the same thing.

Cleaned up

When something odd is found, the text is also shown with the lookalikes turned into the characters they are drawn as and the invisible ones removed. A non-breaking space becomes an ordinary space rather than disappearing, since it was holding two words apart.

Combining marks are left alone. The accent in café is a separate code point and it is meant to be there — it is how the word is spelled, not something that crept in.

No character names for everything

Unicode's full name table is about a megabyte, and almost every row of it would be a name nobody asked for. Names are given for the characters that actually cause trouble; everything else is described by its script and category, which your browser already knows. It is the difference between a page that loads and one that does not.

Nothing is uploaded

Everything runs in your browser. That matters more here than on most pages: the string you are debugging is often a password, a token, or a row out of a customer database.

For turning text into other representations, text to binary and Morse does that, and string escape handles the escaping rules per language.

questions

Why do two identical-looking strings not match?
Almost always a character you cannot see. A zero-width space pasted from a chat window, a non-breaking space from a word processor, or a Cyrillic а inside a Latin word all render the same and compare differently. Paste both strings here and the odd characters are marked.
What is a zero-width space?
U+200B, a character with no width at all. It is legitimate in some scripts for line breaking, but it also travels invisibly through copy and paste, where it silently breaks string comparisons, URLs and passwords.
Why are there three different lengths?
Because "length" means three things. A family emoji is one character to a reader, five code points to Unicode and eight to JavaScript .length. All three are shown, since the gap between them is usually what you came to find.
What does the direction warning mean?
Characters like U+202E reverse the order text renders in without changing how it is stored, so a file named harmlessfdp.txt can display as harmlesstxt.pdf. They are flagged separately because they are used deliberately to deceive.
Does it upload the text?
No. Everything runs in your browser, which matters here because the string you are debugging is often a password, a token or a customer record.