Skip to content
AI Watermark remover

Invisible character remover

Invisible characters embedded in text survive copy and paste but never show up on screen. This page finds them and takes them out, on your machine, without an account and without sending your text anywhere.

Source
0 characters
Cleaned
Nothing to clean yet.

Nothing to clean yet.

Why invisible characters end up in text

Unicode has dozens of codepoints that take up a position in a string without drawing anything. Most of them exist for good reasons. A soft hyphen marks where a word may break. A zero-width joiner holds an emoji together, and bidi controls keep Arabic and Hebrew running the right way. But a codepoint that takes up space and shows nothing is also somewhere to hide a signal. Some AI writing tools mark their output that way, and the marks ride along through copy, paste and email untouched.

This is not only a watermarking problem. Text scraped off a web page or pulled out of a PDF picks them up by accident, and then they break a string comparison, a slug, a database lookup or a diff for reasons nobody can see.

Exactly what gets removed

The list comes from the same table the cleaner runs on, so it cannot drift out of date.

  • Zero-width and directional marksU+200B–U+200F
  • Word joiner and invisible math operatorsU+2060–U+2064
  • Bidirectional overrides and isolatesU+061C, U+202A–U+202E, U+2066–U+2069
  • Deprecated format charactersU+206A–U+206F
  • Soft hyphen, grapheme joiner and byte-order markU+00AD, U+034F, U+FEFF
  • Variation selectorsU+FE00–U+FE0F, U+E0100–U+E01EF
  • Tag charactersU+E0001, U+E0020–U+E007F
  • Interlinear annotation marksU+FFF9–U+FFFB
  • Private-use area charactersU+E000–U+F8FF, U+F0000–U+FFFFD, U+100000–U+10FFFD
  • Unusual spaces, normalized to a plain spaceU+00A0, U+1680, U+2000–U+200A, U+202F, U+205F, U+3000

What it leaves alone

Emoji keep working. A variation selector or zero-width joiner that is holding an emoji together stays where it is, and so do the joiners Persian and Indic scripts use inside words. Those come out only if you ask for it. The tool never touches line breaks, tabs or ordinary punctuation.

Where this comes from

I ported the codepoint table from yasir-mo's AI-watermark-remover-GUI, an MIT-licensed Python project that does the same job from the command line. The table is the part worth stealing: nine categories of codepoint, and if one range in it is wrong the page either leaves a watermark in place or quietly breaks somebody's text.

One piece I could not port cleanly. The upstream project works out whether a joiner is doing visible work before it strips anything, and I could not read that function when I built this, so I rebuilt the rule from the names in the table instead. It handles the four cases I can actually test: a heart with a variation selector, a three-person family emoji, the Scotland flag, and a Persian word with a zero-width non-joiner inside it. If you find text where it guesses wrong, that is the part to blame.

Questions

Codepoints that take up a position in text but render nothing. Zero-width spaces, the byte-order mark, soft hyphens, bidi controls, variation selectors, tag characters and the private-use areas are the common ones. They copy and paste like any other character, which is why they travel so well and why you cannot spot them by reading.