Copy a paragraph of AI-generated text, paste it somewhere else, and it looks identical. Same words, same punctuation. But "looks identical" and "is identical" are different claims, because Unicode contains a whole family of characters that render as nothing at all — zero pixels wide, invisible in every normal font — while still being real bytes in the file. Anyone who controls the text you copy can hide data in those characters, and you'll carry it wherever the text goes.
This isn't a hypothetical. Invisible-character fingerprinting has been used for years to trace leaked documents, and it's now part of the conversation around watermarking AI output. Some of what you'll read about it online is accurate; a fair amount is fearmongering. Let's sort out what these characters actually are, how the hiding trick works, how to check your own text, and — the part most articles get wrong — which kinds of watermarks survive even a perfect cleanup.
The invisible cast of characters
Unicode wasn't designed for sneakiness. Most of these characters exist for legitimate typography: controlling where lines break, how scripts like Arabic join letters, or how emoji combine. The stealth potential is a side effect. Here are the main players:
| Character | Codepoint | Legitimate purpose |
|---|---|---|
| Zero-width space | U+200B | Marks a line-break opportunity without a visible space (used in Thai, long URLs) |
| Zero-width non-joiner | U+200C | Prevents adjacent letters from forming a ligature — essential in Persian and some Indic scripts |
| Zero-width joiner | U+200D | Forces joining; the glue inside compound emoji like the family sequences |
| Word joiner | U+2060 | Prevents a line break at its position, invisibly |
| Byte order mark / ZWNBSP | U+FEFF | Marks byte order at the start of a file; legacy zero-width no-break space elsewhere |
| Variation selectors | U+FE00–U+FE0F, U+E0100–U+E01EF | Select glyph variants (text vs. emoji presentation, CJK variants) |
| Tag characters | U+E0000–U+E007F | A deprecated block mirroring ASCII, originally for language tagging; now mostly used for flag emoji — and steganography |
Every one of these renders invisibly (or attaches invisibly to a neighboring character) in ordinary text. Every one survives copy-paste in most editors, chat apps and CMSes. That combination is the whole trick.
How data gets hidden in plain text
The simplest scheme is binary encoding: pick two invisible characters — say U+200B for 0 and U+200C for 1 — and you can spell out any message eight invisible characters per byte. Sprinkle the sequence between words of a paragraph and you've embedded a user ID, a timestamp, or a session identifier that travels with every copy of the text. A leaked memo comes back to you? Decode the zero-width pattern and you know exactly which recipient's copy it was.
The Unicode tag block, starting at U+E0000, makes this even easier because it's a direct mirror of ASCII. U+E0041 is an invisible "A", U+E0042 an invisible "B", and so on. You don't even need a binary scheme — you can just write an entire hidden sentence, character for character, in tag codepoints. Security researchers have repeatedly demonstrated this as an attack vector too: invisible tag-block instructions pasted into a prompt can smuggle text past human reviewers straight into an AI model, which happily reads what you can't see. Same mechanism, different payload.
Variation selectors offer yet another channel. Since there are 256 of them across the two blocks, a single visible character can carry a full hidden byte appended as a selector, and a short paragraph can smuggle a surprisingly large payload. In early 2024 a widely-shared demo hid an entire message inside what appeared to be a single emoji.
So who actually does this? Document-tracing vendors, some enterprise DLP systems, and occasionaly individual sites that want to fingerprint copied text. Several tools that "humanize" or process AI text have also been caught inserting zero-width characters into their output. Whether the big AI chatbots themselves embed invisible characters is a claim that resurfaces constantly; in our tests, mainstream model output has been clean of them as of mid-2026, and OpenAI publicly walked back a brief experiment where ChatGPT emitted special Unicode spaces. But text passes through a lot of hands between a model and your clipboard — extensions, wrappers, "detection-proof" rewriters — and any of them can add markers. The paranoid move isn't assuming your chatbot watermarks you. It's checking the text, which takes ten seconds.
It's worth separating this family from a related trick: homoglyph substitution. Instead of adding invisible characters, a fingerprinting tool swaps visible ones for lookalikes — a Cyrillic U+0430 "а" for a Latin "a", a non-breaking space U+00A0 for a regular space, a soft hyphen U+00AD that only shows up when a line happens to break there. The text still reads perfectly; the pattern of substitutions is the payload. Homoglyphs are technically visible characters, but for detection and cleanup purposes they belong on the same checklist, because your eyes can't tell the difference and your clipboard doesn't care.
How to detect invisible characters
You have a few options, from manual to instant:
- Paste the text into a hex or Unicode inspector. Anything beyond ASCII shows up immediately as multi-byte sequences —
E2 80 8Bis the UTF-8 signature of a zero-width space, for instance. - Code editors help: VS Code highlights invisible Unicode with a yellow box by default since the "Trojan Source" scare of 2021, and a search for the regex
[-]finds the common ones. - Compare lengths. If a paragraph's character count in one tool disagrees with another tool's count for the "same" text, something invisible is inflating it.
- Or skip the forensics: paste the text into our AI text watermark remover, which flags every suspicious codepoint it finds and produces a cleaned copy. It runs entirely in your browser, so the text never touches a server — worth caring about when the text is exactly the thing you don't want logged somewhere.
A concrete example makes the hex approach less intimidating than it sounds. Take the phrase "hello world" with a zero-width space smuggled between the words. In any hex view, the visible characters are single bytes — 68 65 6C 6C 6F for "hello" — and then, right where you'd expect a lone 20 for the space, you'll see E2 80 8B wedged in as three extra bytes. You don't need to know what any of it means. You just need to notice that eleven visible characters somehow became fourteen bytes, and that's your answer. Byte counts don't lie, which is more than can be said for rendered text.
Cleaning is the easy half. Strip the zero-width and tag characters, normalize exotic spaces to plain U+0020, and the hidden channel is gone. One caution: don't blindly delete every U+200C and U+200D from multilingual text. In Persian, Hindi or emoji-heavy content those characters are doing real work, and removing them visibly breaks the the text. Good cleaning tools are context-aware about this; naive find-and-replace is not.
The watermark that character cleaning can't touch
Here's where I have to be honest with you, because plenty of tools in this space aren't: not all text watermarks live in the characters.
Google DeepMind's SynthID-Text — deployed across Gemini and published in Nature in October 2024 — works differently. Instead of inserting anything into the text, it nudges the model's word choices while the text is being generated. Using a key, the sampler slightly prefers certain tokens in certain contexts. Each individual word looks completely natural; across a few hundred words, the statistical bias forms a signature that Google's detector can recognize. There are no special characters to find. The watermark is the wording.
A zero-width watermark hides in the bytes between the words. A statistical watermark like SynthID-Text hides in the choice of the words themselves — and no character cleaner can remove what was never a character.
What does affect statistical watermarks? Heavy paraphrasing, translation to another language and back, or substantial human editing — anything that replaces enough of the original token choices degrades the signal, and Google's own paper acknowledges this. But light editing leaves it largely intact, and cleaning invisible characters does precisely nothing to it, because there's nothing there to clean.
So the honest breakdown looks like this: invisible-character watermarks are trivially detectable and trivially removable once you know they exist. Statistical watermarks are invisible in a deeper sense, removable only by rewriting, and currently detectable only by whoever holds the key — as of mid-2026 there's no public tool that tells you whether arbitrary text carries SynthID. Two very different beasts that get lumped together under "AI watermarking" in most coverage.
What to actually do
For everyday purposes, the checklist is short. Before you publish or send text that passed through tools you don't fully control, inspect it — hex viewer, editor highlighting, or a purpose-built cleaner. Strip what shouldn't be there. If the text also came out of an image or a document rather than a chat window, remember that files carry their own metadata layer on top of the text; a photo of a document, for example, is better handled by an image metadata remover than by any text tool, and the same logic extends to C2PA provenance data, which we've covered in our guide to content provenance.
And keep your threat model straight. Invisible characters answer the question "did someone tag this specific copy of the text?" Statistical watermarks answer "did a particular model generate this wording?" Cleaning handles the first completely and the second not at all. Anyone selling you a one-click fix for both is selling you something — the characters you can delete; the wording, you'd have to rewrite.