Magic Tools
Utility GuidesBy CooconAugust 16, 2026279 views8 min read

AI Text Watermark Checker: Detect Hidden Unicode Characters

Copy a piece of AI-generated text and paste it into a hexadecimal editor, and you might see some 'non-existent' things: dozens of Unicode characters that take up no display width, make no sound, but actually occupy code points. They travel with copy and paste, and can be used to mark text sources, track leakage channels, and even encode a complete hidden plaintext.

This article explains the six types of character-level steganography one by one: what each character is, what its normal purpose is, what it looks like when abused as a watermark, and how to detect and remove it. It also clarifies something most similar articles don't say—where the capability boundaries of these tools lie, and what kind of watermarks character scanning can never detect.

You can use MagicTools' AI Watermark Detector at any time for comparative experiments: paste the text for character-by-character scanning, all done locally in the browser, and the text is not uploaded.

Six Types of Invisible Characters: From 'Classic Watermarks' to 'Steganographic Channels'

1. Zero-Width Characters (zero-width)

The most classic type, with five members:

Code Point Name Abbreviation
U+200B Zero-Width Space ZWSP
U+200C Zero-Width Non-Joiner ZWNJ
U+200D Zero-Width Joiner ZWJ
U+2060 Word Joiner WJ
U+FEFF Zero-Width No-Break Space (BOM) BOM

Their legitimate purpose is typesetting control: ZWSP tells the browser 'line break here is allowed', ZWNJ/ZWJ control glyph joining for Arabic, Hindi, and other connecting scripts, and BOM marks file byte order. When abused, the simplest trick is to treat each zero-width character as a bit—ZWSP is 0, ZWNJ is 1—a sequence of 8 characters can hide a byte. The text appears unchanged, but the 'fingerprint' is preserved intact with copy and paste.

2. Direction Control Characters (direction)

U+200E/200F (LRM/RLM), U+202A–202E (Embeddings and Overrides), U+2066–2069 (Isolates). Designed for right-to-left scripts like Arabic and Hebrew to mix with Latin text.

This type's danger goes beyond watermarks: U+202E (RLO, Right-to-Left Override) can make a filename invoice_exe.pdf actually be invoice_fdp.exe, a classic phishing tactic; the "Trojan Source" attack (CVE-2021-42574) disclosed in 2021 used direction control characters to make source code display order in editors inconsistent with logical order read by compilers. Direction control characters in ordinary Chinese-English text are almost always suspicious.

3. Variation Selectors (variation-selector)

U+FE00–FE0F (VS1–VS16) and supplementary plane U+E0100–E01EF (VS17–VS256). Legitimate purpose is to specify different glyphs for the same character—most commonly VS16 (U+FE0F) switches a symbol to emoji color form.

When abused, it becomes a high-capacity steganographic channel: 256 variation selectors can exactly encode a byte, and attaching them to any visible character can hide arbitrary binary data in an ordinary sentence. Paul Butler's article "Smuggling arbitrary data through an emoji" in early 2024 made this technique widely known.

4. Tag Characters (tag)—A type that can hide complete plaintext

U+E0000–E007F, the most 'nominal' block in Unicode: originally designed for language tags, deprecated in 1999, but characters still exist. Among them, U+E0020–U+E007E correspond one-to-one with ASCII printable characters—add 0xE0000 to the code point of any ASCII character to get its invisible version.

This means a sequence of Tag characters can directly encode a complete English sentence, a URL, a command, and nothing shows on screen. This is also the technical basis for 'invisible prompt injection' attacks against LLMs: instructions invisible to the human eye, but the model's tokenizer reads them clearly. When detecting such characters, it's worth decoding consecutive sequences to see the content—the AI Watermark Detector automatically restores consecutive Tag sequences to ASCII plaintext for display.

An implementation detail: decoding must be grouped by 'continuous segments'. If two Tag sequences are separated by visible text, they are two independent hidden messages, and concatenating them yields incorrect content—this is a bug we actually caught in unit tests.

5. Special Spaces (space)

U+00A0 (Non-Breaking Space NBSP) and U+202F (Narrow No-Break Space NNBSP). They 'look like spaces but have different code points', and their normal purpose is typesetting (spacing between French numbers and units, preventing orphaned lines). As a watermark technique, replacing some regular spaces with NBSP constitutes a binary channel. This type is the least dangerous, and the correct approach when cleaning is replace with regular spaces instead of deleting—direct deletion would merge two words together.

6. Soft Hyphen (soft-hyphen)

U+00AD. Only displays as a hyphen during line-break hyphenation, otherwise completely invisible, and can also be used to encode bits via 'presence/absence'.

Why Emojis Are Prone to False Positives

Any naive implementation that 'raises an alarm upon seeing invisible characters' will fail on emojis. Modern emojis rely heavily on two types of invisible characters for normal combinations:

  • ZWJ (U+200D): The family emoji 👨‍👩‍👧‍👦 is actually "man + ZWJ + woman + ZWJ + girl + ZWJ + boy", four emojis joined by three zero-width joiners.
  • VS16 (U+FE0F): ❤️ is "heart symbol U+2764 + VS16", without VS16 it's the text-style ❤

A normal chat record with a few emojis, a naive scan would report dozens of 'hidden characters', and users seeing a screen full of red warnings lose trust in the tool. The correct approach is context judgment: ZWJ or VS16 adjacent to pictographs (Extended_Pictographic) belong to normal combinations, count individually and don't include in suspicious counts. When cleaning, preserve these combinations by default (otherwise family emojis break apart into four people), and only delete them when the user explicitly selects 'aggressive mode'.

Capability Boundaries: Character Scanning Cannot Detect Statistical Watermarks

This is the most important section of the article.

The six types above share a common point: the watermark exists in the characters themselves, so character-by-character scanning can always find it, and finding it allows deletion. But the text watermarks deployed by mainstream AI vendors are not of this type.

The invisible watermarks embedded by Claude in generated text since August 2026, and Google's SynthID-Text, use sampling watermarks: during the model's sampling stage for each word, a slight probability bias is applied to candidate words, making sufficiently long text exhibit statistical patterns recognizable by specific detectors. The watermark is hidden in 'which words were chosen', not in any character—every code point of the text is ordinary, clean in a hexadecimal editor. The principles, legal background, and officially acknowledged detection boundaries of this mechanism are fully explained in "What is Claude's Invisible Watermark".

So to clarify:

  • What character scanning tools can do: Detect and clean all six types of character-level steganography—this part is verifiable, deterministic; what is found is what is there.
  • What character scanning tools cannot do: Detect or remove statistical watermarks. Any tool on the market claiming to 'one-click remove Claude/ChatGPT watermarks' targets mechanisms that don't exist in these models' outputs.
  • Images and audio are another line: C2PA signature metadata and SynthID media watermarks have their own verification methods, see "C2PA Content Credentials Verification Guide" and "OpenAI Content Provenance API Interpretation".

When Is an Invisible Character Check Needed

  • Pre-release content QA: From websites, chat windows, AI tools, copy text and scan before pasting into CMS, PDF, or e-books to avoid layout anomalies, search mismatches, or word count deviations caused by invisible characters.
  • Code review: Invisible characters in source code may change program logic (Trojan Source) or cause text-matching based editing tools to repeatedly fail— the latter we encountered in our own development process: a regex containing 14 literal invisible characters caused an AI editing tool to fail four times consecutively, finally resolved by changing all to \uXXXX escape sequences.
  • Suspecting text has tracking markers: Investigating internal document leaks, receiving text from unknown sources.
  • Before pasting to LLMs: Prevent invisible prompt injection.

Frequently Asked Questions (FAQ)

Do invisible characters persist with copy and paste?

Yes, this is why they can be used as watermarks. They are real Unicode code points and are preserved as-is in copy, paste, and file storage. However, note that many platforms (some input fields, CMS, chat software) perform normalization cleaning during storage, so invisible watermarks may also 'naturally fall off' during cross-platform transmission—not detecting them doesn't mean they never existed.

Does detecting invisible characters mean the text is AI-generated?

No. Invisible characters have many sources: NBSP and soft hyphens copied from Word/web pages, direction control characters for multilingual typesetting, normal combination characters in emojis, all unrelated to AI. Conversely, mainstream AI models' text watermarks are statistical and contain no invisible characters. Character detection answers 'what is hidden in the text', not 'who wrote the text'.

Will cleaning invisible characters damage the main text?

Not if rules are appropriate: special spaces are replaced with regular spaces (preserving word boundaries), ZWJ/VS16 used for emoji combinations are preserved by default (keeping emojis intact), and other categories are deleted directly. Visible text, punctuation, and line breaks remain untouched.

Will online detection tools upload my text?

It depends on the implementation. MagicTools' AI Watermark Detector is a pure front-end implementation: scanning and cleaning are pure functions in the browser, with no network requests, and text does not leave your device. When handling sensitive content, it's recommended to prioritize such locally processed tools or verify offline.

Is character detection the same as "AI content detection"?

Completely different. AI content detectors make statistical guesses about writing style, with known false positive rates; invisible character detection is deterministic code point scanning, reporting verifiable facts—which character is at which position, exactly one less or one more. The former is probabilistic judgment, the latter is objective examination.

Related Articles

Dev Breakfast · 2026-09-30

Today's headline: Anthropic Prospectus: Revenue Increased 12 Times, Loss of 42 Billion. Plus 4 more: 0.8B Model Trained at Home: Choose One from 254 Options in 28 ms; 7 ESP32-S3 Chips Chained Together to Run a 0.5B 1.58-bit Model; and more.

daily-intelSep 30, 20268 min
48
Claude Code install errors, reproduced: EACCES, a 600s mirror stall, Node 20 silently getting an old version, a region-block install.sh, and the native installer removing your npm copy

Claude Code install errors, reproduced: EACCES, a 600s mirror stall, Node 20 silently getting an old version, a region-block install.sh, and the native installer removing your npm copy

I reproduced every Claude Code install failure I could on macOS: 15 verbatim errors, each with wall time and exit code. npm -g into /usr/local fails with EACCES, exit 243. A cache dir that is merely 0555 gets blamed on root-owned files, with sudo chown advice. From Beijing, npmmirror took 147s and then >600s, npmjs 11-12s (2 samples each). On Node 20, an unpinned install silently lands on 2.1.197. Fetching claude.ai/install.sh from a blocked region gives curl exit 0 and a 447 KB HTML page. The native installer runs npm uninstall -g on your npm copy without saying so; it removed mine.

claude-codetroubleshooting+5
pitfallsSep 29, 202611 min
75

Dev Breakfast · 2026-09-29

Today's headline: Adding 'Do not guess' cuts hallucination rate from 71% to 20%. Plus 4 more: Go's import path tied to GitHub: how much code changes when switching hosting; Sonnet 5.5 released: Terminal-Bench jumps from 10.3% to 70.6%; and more.

daily-intelSep 29, 20267 min
205
DeepSeek Harness Test: One Model, Three Harnesses — Claude Code 15/15, Codex CLI 15/15, Bare API 0/15 (and 5 Fake "Done"s)

DeepSeek Harness Test: One Model, Three Harnesses — Claude Code 15/15, Codex CLI 15/15, Bare API 0/15 (and 5 Fake "Done"s)

Same DeepSeek model (deepseek-v4-pro), three harnesses, five tasks (read / write / edit / run a command / multi-step), three rounds each, every side effect checked on disk. Claude Code on DeepSeek's Anthropic endpoint: 15/15, median 4.17s, ¥0.159 per task. Codex CLI 0.157.1 on the Responses endpoint: 15/15, median 15.52s, ¥0.022 per task — one seventh. Bare chat/completions: 0/15, and 5 of those rounds replied DONE or EDITED with nothing on disk. The differences are the harness: DeepSeek partitions its prompt cache by metadata.user_id, so every `claude -p` pays ~15K uncached tokens; Codex has no file tools and does everything through shell; on HTTP 500 Claude Code retries 10 times over ~175s while Codex quits in ~25s, and on 429 Codex doesn't retry; on 120KB of output Claude Code shows the first 2KB, Codex head + tail. And wire_api = "chat" is gone in Codex 0.157.1 — use responses.

claude-codeprompt-caching+6
hands-onSep 28, 202613 min
117

Published by Magic Tools