Invisible Unicode characters: a complete reference

· 12 min read

Unicode contains roughly 4,000 code points that render as nothing, plus about 137,000 private-use code points whose appearance depends entirely on the font. Most have legitimate uses. A handful — the Unicode Tags block, the invisible math operators, and long runs of zero-width joiners — almost never appear in ordinary text and are strong evidence that data has been hidden.

What makes a character invisible

There is no single Unicode property that means "invisible". Characters disappear from rendered text for several unrelated reasons, and the reason matters when you decide what to do about them.

The largest group is Default_Ignorable_Code_Point: about 4,174 code points that conforming renderers are instructed to hide when they cannot be displayed meaningfully. This includes assigned formatting characters and — importantly — large blocks of unassigned code points reserved for future formatting use. Those reserved ranges can never carry legitimate meaning today, which makes them a ready-made covert channel.

A second group is general category Cf (Format): 170 code points that control how surrounding text is shaped or ordered without producing a glyph of their own. A third is Cc (Control): the 65 C0 and C1 control characters inherited from ASCII and Latin-1. A fourth is characters that produce whitespace of unusual width, which are not invisible so much as indistinguishable from an ordinary space.

The categories, and what each is actually for

CategoryExamplesLegitimate useSuspicious when
Zero-widthU+200B, U+2060, U+FEFFLine-break hints, byte-order mark at file startAppearing mid-sentence, or in runs
JoinersU+200C ZWNJ, U+200D ZWJArabic and Indic orthography, emoji sequencesBetween Latin letters, or in runs of two or more
Invisible math operatorsU+2061–U+2064MathML semantic markupAlmost anywhere else — this is StegCloak's alphabet
Unicode TagsU+E0000–U+E007FOnly the England, Scotland and Wales flag emojiAny other use — this block smuggles ASCII directly
Bidirectional controlsU+202A–U+202E, U+2066–U+2069Mixing right-to-left and left-to-right textOverrides in source code (Trojan Source)
Variation selectorsU+FE00–U+FE0F, U+E0100–U+E01EFEmoji presentation, CJK glyph variantsAfter Latin letters; 240 selectors is a wide channel
Blank-like fillersU+115F, U+1160, U+3164, U+FFA0Historic Hangul compositionModern text — the classic "blank username" trick
Unusual spacesU+00A0, U+202F, U+2007, U+3000Typography, non-breaking layoutMixed unpredictably through a document
Private useU+E000–U+F8FF and two supplementary planesFont icon sets, corporate logosIn text meant to travel between systems

The Unicode Tags block deserves special attention

U+E0000 to U+E007F mirrors printable ASCII one-to-one: U+E0041 is a tag "A", U+E0061 a tag "a". A run of them encodes arbitrary text that renders as absolutely nothing in every major browser, editor and chat client, while remaining fully present in the underlying string.

Unicode deprecated the block's original language-tagging purpose. Its only surviving sanctioned use is three emoji: the England, Scotland and Wales flags, each built from a black flag followed by tag letters and a terminator. Everything else in that block is smuggled data.

This is the channel behind most demonstrations of invisible prompt injection: instructions hidden in a document that a person reading it cannot see, but that a language model consuming the raw text reads as ordinary input.

What not to remove

Aggressive stripping breaks real text. A cleaner that deletes every non-ASCII code point will corrupt Persian, Arabic and Indic writing, flatten emoji families into unrelated single characters, and turn the Welsh flag into a plain black one.

Three rules avoid nearly all of that damage. Replace unusual spaces with an ordinary space rather than deleting them, or words merge. Keep zero-width joiners that sit between letters of a script that uses them, or inside an emoji sequence. Keep variation selectors that follow a base which legitimately takes one.

Private-use characters deserve a fourth rule: report them, do not delete them. They are what font icon sets and corporate logos are made of, and they are usually visible to the reader even though no standard defines them.

Frequently asked

How many invisible Unicode characters are there?
Around 4,174 code points carry the Default_Ignorable_Code_Point property in Unicode 17, which is the closest formal definition of "renders as nothing". Adding private-use areas, surrogates and noncharacters — code points whose appearance is undefined or which are invalid in interchange — brings the total set worth scanning to roughly 143,872.
Is a zero-width space always malicious?
No. U+200B is a legitimate line-break opportunity hint, and U+FEFF is a valid byte-order mark at the start of a file. What is anomalous is finding them scattered through the middle of prose, or in runs — a single legitimate use never chains them together.
Can I see invisible characters in a normal text editor?
Usually not. Most editors render them as nothing by design. Some developer editors can be configured to highlight them, but the reliable way to find them is to inspect the text by code point rather than trusting what is drawn on screen.

Keep reading