AI Text Watermark Remover — Remove Hidden Unicode from AI Text
One engine for text from any assistant, in any language, including right-to-left scripts.
Hidden character report
Paste text to scan
Hidden characters across AI assistants
Different assistants render differently, but they share the same problem: what you see is a rendered page, and what you copy is a character stream. The gap between the two is where invisible characters live. A tool built for one assistant's output tends to work on another's, because the characters themselves come from Unicode rather than from any one product.
That is why this page exists as a separate entry point. The engine behind it is identical to the one on every other page of this site — the same published table, the same report, the same formatting rules. Only the explanation changes.
Bidirectional marks and mixed-language text
If you write in a right-to-left script, or mix one with a left-to-right language, you have met directional controls whether or not you knew their names. They tell a text engine which way to lay out a run of characters. Inside a chat window they do a real job. Copied into an editor that renders them differently, they can flip the punctuation around a phrase or reorder a line.
The engine removes all twelve of them, including the isolate controls that replaced the older embedding pairs. For text in a single direction this changes nothing visible. For mixed text it usually restores the order you expected.
Copying from a chat window into a document
The failure mode is rarely dramatic. A word refuses to break at the end of a line. A search for a phrase you can see on screen returns nothing. A spell checker flags a word that looks correct. Each of these has a mundane explanation, and an invisible character is one of the most common ones.
Because the tool shows counts per character type, you can tell these cases apart. One zero-width space in a long paragraph is noise. Forty of them, evenly spread, means the text was copied from a rendered answer without any editing in between.
What stays exactly the same
Letters, digits, punctuation, capitalisation, accents, emoji, tabs and paragraph order. The engine reads your text one code point at a time and copies everything forward unless it matches an entry in the table, so characters outside that table cannot be affected even in principle.
Emoji deserve a mention because they are stored as pairs of code units. The engine iterates by code point rather than by code unit, so a family emoji or a flag comes out intact instead of being split into broken halves.
What invisible character watermarks actually are
The phrase 'AI watermark' is used loosely to describe two distinct techniques that have almost nothing in common. One is a statistical watermark — a pattern baked into the probability distribution a language model uses when it picks its next token. That pattern is invisible at the character level and cannot be detected or removed by any tool that works on the output text. The other is a character-level watermark: invisible Unicode characters inserted into the text after generation, either by the model's output pipeline or by a post-processing step. This tool deals entirely with the second kind.
Zero-width characters and homoglyph substitutions are the two mechanisms used in character-level watermarking. Zero-width characters are Unicode code points that render as nothing — they take up no horizontal space and produce no visible glyph, but they exist in the character stream and can encode a pattern. A document with one zero-width space every thirty words carries a different fingerprint than one with them every twenty-five words, or one with them placed only after punctuation. Homoglyph substitution replaces a common Latin letter with a visually identical character from another script: a Cyrillic 'а' (U+0430) in place of a Latin 'a' (U+0061), or a Greek 'ο' (U+03BF) in place of a Latin 'o' (U+006F). The page looks identical. The byte stream is different.
Both techniques exploit the gap between what a rendering engine shows you and what the underlying character stream contains. A browser or document viewer applies font shaping, ligature rules, and glyph mapping — the visual layer. The character stream is what lives in memory and gets transmitted when you copy. Tools that operate on the character stream, like this one, can see things the visual layer hides. That is the basic mechanism: the watermark lives below the rendering layer, and the only way to inspect it is to work at the code-point level.
How to check your own text for hidden characters
The fastest self-check requires nothing more than a browser console. Open any page, press F12, select the Console tab, and run this line: [...yourText].filter(c => c.codePointAt(0) > 127 || c.codePointAt(0) < 32).map(c => 'U+' + c.codePointAt(0).toString(16).toUpperCase().padStart(4,'0') + ' at index ' + [...yourText].indexOf(c)). Replace yourText with the string you want to inspect. The spread operator splits the string by Unicode code point rather than by UTF-16 code unit, which matters for supplementary characters above U+FFFF. The filter selects everything outside printable ASCII — that includes every zero-width character, every bidirectional control, every homoglyph from another script, and every non-breaking space. The result is a list of suspicious code points with their positions.
For homoglyphs, the check is slightly different. A Cyrillic 'а' passes the ASCII filter because it is a printable character — it just happens to look like a Latin one. To catch it, run: [...yourText].map((c,i) => ({i, cp: c.codePointAt(0).toString(16), c})).filter(({cp}) => ['0430','043e','03bf','0435','0440','0441','0445','0440','0441'].includes(cp)). This checks for the most commonly substituted Cyrillic letters. A more thorough check would compare the Unicode block of each letter against the expected script of the document — Latin characters appearing in a block of Cyrillic text, or vice versa.
The report this tool generates does the same work automatically. Each row in the report is a character type that was found, with its Unicode code point and a count. The total at the bottom is the number of characters that would be removed if you ran the cleaner on the same text. If you want to cross-check the report by hand, the console one-liner and the tool output should agree — if they produce different counts, the most likely explanation is that you changed the input text between the two checks.
What cleaning does and does not guarantee
Cleaning removes every character this tool's published table covers: zero-width spaces, zero-width non-joiners, zero-width joiners, word joiners, byte-order marks, soft hyphens, non-breaking spaces, bidirectional control characters, and the most common homoglyphs used in substitution watermarking. After the cleaner runs, none of those characters are present in the output. That is a concrete, verifiable guarantee about the character stream.
What the cleaner does not and cannot guarantee is that any detection system will treat the cleaned text differently than it treated the original. Statistical watermarks — the kind embedded in a model's output distribution — are not in the character stream and are therefore untouched. A system that scores text based on n-gram patterns, sentence structure, vocabulary distribution, or stylistic features will produce the same score before and after cleaning, because none of those features live in the character layer. If a document contains a statistical watermark, removing invisible characters does nothing to it.
Detection systems vary enormously in what they measure. Some look for invisible characters — this cleaner removes those. Some look for statistical patterns — this cleaner does not affect those. Some combine both. Without knowing exactly what a given system checks, there is no way to predict how it will respond to cleaned text. The honest description of what this tool does is this: it removes the invisible characters and homoglyphs in its table. Whether that changes any detection outcome depends entirely on what the detection system is measuring, and that is outside this tool's scope.
Characters this tool looks for
25 invisible characters and formatting controls, with the action taken on each one.
| Character | Code point | Action | What it does |
|---|---|---|---|
| Zero-width characters | |||
| Zero Width Space | U+200B | Removed | Invisible separator with no width. Commonly left behind when text is copied out of a chat window. |
| Zero Width Non-Joiner | U+200C | Removed | Invisible character that blocks two letters from joining in scripts such as Arabic or Devanagari. |
| Zero Width Joiner | U+200D | Removed | Invisible character used to glue emoji sequences together. Stray copies can break word wrapping. |
| Zero Width No-Break Space (BOM) | U+FEFF | Removed | Byte order mark. Harmless at the start of a file, invisible noise anywhere else. |
| Word Joiner | U+2060 | Removed | Tells a text engine not to break a line here. Invisible, and easy to carry along by accident. |
| Mongolian Vowel Separator | U+180E | Removed | A legacy invisible separator from Mongolian script that now renders as nothing at all. |
| Bidirectional controls | |||
| Left-to-Right Mark | U+200E | Removed | Directional hint for mixed-script lines. Invisible on screen but present in the character stream. |
| Right-to-Left Mark | U+200F | Removed | Mirror of the left-to-right mark, used to steer the order of mixed-direction text. |
| Arabic Letter Mark | U+061C | Removed | Invisible directional marker for Arabic text. Rarely intentional outside its original document. |
| Left-to-Right Embedding | U+202A | Removed | Opens an embedded left-to-right run. Unpaired copies can scramble the order of a sentence. |
| Right-to-Left Embedding | U+202B | Removed | Opens an embedded right-to-left run. Left behind after copy-paste, it can flip nearby punctuation. |
| Pop Directional Formatting | U+202C | Removed | Closes an embedded directional run. Without its partner it is pure invisible noise. |
| Left-to-Right Override | U+202D | Removed | Forces following characters to display left-to-right regardless of their own direction. |
| Right-to-Left Override | U+202E | Removed | Forces following characters to display right-to-left. A common cause of text that looks reversed. |
| Left-to-Right Isolate | U+2066 | Removed | Modern replacement for the embedding controls. Still invisible, still travels with copied text. |
| Right-to-Left Isolate | U+2067 | Removed | Isolates a right-to-left run from the surrounding paragraph direction. |
| First Strong Isolate | U+2068 | Removed | Isolates a run whose direction is decided by its first strong character. |
| Pop Directional Isolate | U+2069 | Removed | Closes an isolate opened by one of the isolate controls above. |
| Formatting controls | |||
| Soft Hyphen | U+00AD | Removed | A hyphen the reader only sees if the word happens to break at the end of a line. |
| Carriage Return (CR) | U+000D | Removed | Half of a Windows line ending. Kept on its own it produces doubled spacing in most editors. |
| Markdown Asterisk Marker | U+002A | Removed | Bold or italic marker such as ** left behind when text is copied in its raw form. Turn this group off to keep Markdown styling marks. |
| Markdown Backtick Marker | U+0060 | Removed | Inline-code backtick left behind after copying raw assistant output. Turn this group off to keep inline code marks. |
| Invisible spaces | |||
| No-Break Space | U+00A0 | → space | Looks exactly like a space but stops a line from breaking there. A frequent copy-paste leftover. |
| Figure Space | U+2007 | → space | A space as wide as a digit, used to align numbers in tables. Replaced with a normal space. |
| Narrow No-Break Space | U+202F | → space | A thin, non-breaking space from French typography. Replaced with a normal space. |
Frequently Asked Questions
▸Which assistants does this work with?
Any of them. The engine does not know or care where the text came from — it matches characters against a published Unicode table. If the text contains the characters listed in that table, they are found and removed, whatever produced them.
▸Does it handle right-to-left text?
Yes. All twelve bidirectional controls are removed, including the isolate controls used by modern text engines. Arabic, Hebrew, Persian and mixed-direction paragraphs are processed the same way as any other text, and the letters themselves are never reordered.
▸Does it work on long documents?
Yes. Paste as much as you like — there is no size limit. Very large inputs are flagged in the report area so you know why processing took a moment, but they are handled the same way as short ones, entirely inside your browser.