Откуда берутся невидимые символы
Ни один из них не вводится намеренно. Интерфейс чата отображает ответ ассистента как HTML, а HTML приносит неразрывные пробелы (U+00A0) вокруг чисел и после некоторых знаков препинания, пробелы нулевой ширины (U+200B) там, где длинному слову разрешили переноситься, и мягкие переносы (U+00AD) там, где его разрешили разрывать. Рендереры Markdown добавляют селекторы вариантов рядом с символами. Текстовые процессоры и PDF добавляют типографские пробелы (тонкий, волосяной, полукруглая, круглая шпация) и фигурные кавычки. Windows добавляет концы строк CRLF и иногда маркер порядка байтов (U+FEFF) в начале файла. Копирование текста захватывает всё это, и вставленный результат выглядит идентично, но сравнивается, ищется grep-ом, хешируется и компилируется иначе.
Скрытый текст и водяные знаки
В Unicode есть блок tag-символов (U+E0000–U+E007F), по одному на каждый символ ASCII, которые не отображает ни один шрифт. Они предназначались для языковой разметки и сейчас допустимы только внутри нескольких эмодзи-флагов. Поскольку они невидимы, но переживают копирование-вставку, их используют, чтобы спрятать второе сообщение внутри видимого: prompt injection в документе, который прочитает AI-ассистент, отпечаток, идентифицирующий, кому был выдан текст, или способ протащить инструкции мимо фильтра. Тот же трюк возможен с последовательностями символов нулевой ширины (каждый — один бит) и с селекторами вариантов (их 256, то есть по одному на байт). Очистка удаляет все три вида и для tag-символов показывает декодированный скрытый текст.
Чего она не может удалить — это статистический водяной знак, где паттерн заложен в выборе слов, а не в каких-либо символах. В этом случае в тексте просто нечего вырезать.
Управляющие символы направления письма
Переопределения и изоляты справа налево (U+202E, U+2066–2069) меняют порядок отображения последующего текста. В исходном коде это атака «Trojan Source» (CVE-2021-42574): комментарий, который отображается после условия, но компилируется до него. Компиляторы и GitHub теперь предупреждают о них; этот инструмент их удаляет. Инспектор Unicode показывает каждый с точной позицией, если вам нужно увидеть, а не вырезать.
Почему некоторые опции отключены по умолчанию
- Типографские кавычки и тире — настоящие символы, уместные в прозе. Включайте это, когда текст предназначен для кода, конфигурационного файла или shell, где
“— не", а–— не-. - Буквы-двойники (кириллическая
авместо латинскойa) подозрительны только в тексте, который в остальном латинский; в этом случае очистка помечает их, а кириллический абзац не трогает. Их замена меняет буквы, поэтому это выбор, а не умолчание. - Символы для частного использования — в большинстве случаев иконки из иконочных шрифтов. В других местах они отображаются квадратиками и безвредны.
- Селекторы вариантов удаляются только после букв и цифр, где им нечего делать; после эмодзи и символов они определяют отрисовку глифа и сохраняются.
То же в командной строке
perl -CSD -pe 's/[\x{200B}-\x{200D}\x{2060}\x{FEFF}\x{00AD}\x{E0000}-\x{E007F}]//g; s/\x{00A0}/ /g' in.txt
sed -i 's/\xC2\xA0/ /g; s/\xE2\x80\x8B//g' file.txt # NBSP и ZWSP как байты UTF-8
grep -nP '[^\x00-\x7F]' file.txt # показать каждую строку с не-ASCII
cat -A file.txt | head # ^M для CR, M-BM- для NBSP Вопросы
Удаляет ли это водяные знаки AI?
Удаляется каждая метка на уровне символов: символы нулевой ширины, tag-символы, селекторы вариантов и необычные пробелы — всё, чем текст можно невидимо пометить. Водяной знак, закодированный в самом выборе слов, не состоит из символов, и никакая очистка его не удалит.
Почему текст из ChatGPT или Claude содержит скрытые символы?
В основном как побочный эффект отрисовки: ответ показывается как HTML, а копирование HTML приносит неразрывные пробелы, пробелы нулевой ширины в точках переноса и типографскую пунктуацию. Некоторые инструменты и документы намеренно добавляют tag-символы или последовательности нулевой ширины. Список находок показывает, что именно у вас есть.
Сломает ли это эмодзи?
Нет. Zero-width joiner, склеивающий последовательности эмодзи (👨👩👧), сохраняется, когда стоит между двумя эмодзи; селекторы вариантов после эмодзи и в keycap сохраняются, как и tag-символы, из которых состоят флаги регионов. Удаляются только joiner-ы между обычными буквами.
Текст куда-то загружается?
Нет. Страница полностью работает в вашем браузере; ничего не отправляется на сервер. Вставляйте что угодно.
В чём отличие от инспектора Unicode?
Инспектор перечисляет каждый символ с его кодовой точкой, байтами и названием. Очистка группирует проблемы, объясняет их и выдаёт очищенный текст. Используйте инспектор для расследования, очистку — для исправления.