Не хотите читать? Посмотрите демо.

Символы нулевой ширины — это непечатаемые управляющие символы, которые не отображаются большинством приложений. Н?апример, в э?то пред?ложение я вст?авил де?сять про??белов н?улевой ширины, вы эт?о замет?или? (Подсказка: вставьте предложение в Diff Checker, чтобы увидеть местоположение символов!). Эти символы можно использовать как уникальные «отпечатки» текста для идентификации пользователей.


Безусловно, он может здесь быть. И вы никогда не догадаетесь

Зачем?


Ну, изначальная причина не слишком интересна. Несколько лет назад я с командой участвовали в соревнованиях по различным видеоиграм. У команды была приватная страничка для важных объявлений, среди прочего. Но в итоге эти объявления стали репостить в других местах, с издевательствами над командой, раскрывая конфиденциальную информацию и командную тактику.

Защита сайта казалась довольно стойкой, поэтому мы выдвинули предположение, что действует инсайдер, который входит по логину и паролю, а потом просто копирует объявление и размещает в другом месте. Поэтому я разработал скрипт, который в каждом объявлении невидимо отпечатывает имя пользователя, которому отображается это объявление.

После недавнего поста Зака Айсана стало понятно, что людям интересна тема непечатаемых символов. Так что я решил опубликовать этот метод здесь вместе с интерактивной демонстрацией для всех. Примеры кода обновлены для современного JavaScript, но общая логика одинакова.

Как?


Точные шаги и логика описаны ниже, но если в двух словах: строка имени пользователя преобразуется в двоичную форму, затем двоичный файл преобразуется в серию непечатаемых символов, представляющих каждый бит. Потом непечатаемая строка незаметно вставляется в текст. Если текст опубликован на другом сайте, строку непечатаемых символов можно извлечь и провести обратный процесс, чтобы выяснить имя пользователя, который сделал копипаст!

Фингерпринтинг текста


1. Получить имя пользователя, вошедшего в систему, и преобразовать его в двоичный файл.

Здесь мы просто преобразуем каждую букву имени пользователя в двоичный эквивалент.

const zeroPad = num => ‘00000000’.slice(String(num).length) + num;
const textToBinary = username => (
  username.split('').map(char =>
    zeroPad(char.charCodeAt(0).toString(2))).join(' ')
);

2. Взять имя пользователя в бинарном формате и преобразовать его в непечатаемые символы

Следующий скрипт перебирает двоичную строку и преобразует каждый бит 1 в непечатаемый пробел, каждый 0 — в непечатаемый символ запрета лигатур (non-joiner). После преобразования каждой буквы вставляем непечатаемый символ разрешения лигатур (joiner) — и переходим к следующей.

const binaryToZeroWidth = binary => (
  binary.split('').map((binaryNum) => {
    const num = parseInt(binaryNum, 10);
    if (num === 1) {
      return '?'; // zero-width space
    } else if (num === 0) {
      return '?'; // zero-width non-joiner
    }
    return '?'; // zero-width joiner
  }).join('') // zero-width no-break space
);

3. Вставка «имени пользователя» в непечатаемый конфиденциальный текст

Здесь просто вставляем блок непечатаемых символов в конфиденциальный текст.

Извлечение имени пользователя из помеченного текста


Те же действия в обратном порядке.

1. Извлечь непечатаемое «имя пользователя» из конфиденциального текста

Удалить конфиденциальный текст из строки, оставив только непечатаемые символы.

2. Преобразовать непечатаемое «имя пользователя» обратно в двоичный файл

Здесь мы разбиваем строку на фрагменты, с учётом добавленных межбуквенных разделителей. Это даёт эквивалент в управляющих символах для каждой буквы имени пользователя! Перебираем символы и возвращаем 1 или 0, чтобы воссоздать двоичную строку. Если не находим соответствующий 1 или 0, то значит попали на межбуквенный разделитель (символ разрешения лигатур) и, таким образом, завершиили двоичное преобразование для символа: можно добавить к строке один пробел и переходить к следующему символу.

const zeroWidthToBinary = string => (
  string.split('').map((char) => { // zero-width no-break space
    if (char === '?') { // zero-width space
      return '1';
    } else if (char === '?') {  // zero-width non-joiner
      return '0';
    }
    return ' '; // add single space
  }).join('')
);

3. Преобразование имени пользователя из двоичного формата обратно в текст

В конце концов, анализируем двоичную строку и преобразуем каждую серию 1 и 0 в соответствующий символ.

const binaryToText = string => (
  string.split(' ').map(num =>
    String.fromCharCode(parseInt(num, 2))).join('')
);

Заключение


Компании как никогда много внимания уделяют утечкам информации и поиску инсайдеров. Этот лишь один из многих трюков, которые можно использовать. В зависимости от направления вашей работы, может быть жизненно важно понимать риски, связанные с копированием текста. Очень немногие приложения отображают непечатаемые символы. Например, вы можете предположить, что ваш терминал попытается их отобразить (мой нет!).

Если вернуться к секретной доске объявлений, то план сработал как надо. Вскоре после внедрения скрипта вышло новое объявление. В течение нескольких часов текст распространили в другом месте с прикрепленной непечатаемой строкой. Имя пользователя виновника успешно идентифицировали, и его забанили: хэппи-энд!

Конечно, есть определённые оговорки по использованию этого метода. Например, если пользователь знает о скрипте, то теоретически может заменить непечатаемые символы, чтобы подставить другого человека. Так что лучше вместо имени пользователя вставлять уникальный секретный ID.

Чтобы поиграться со скриптом, запускайте демо или смотрите исходный код.

Комментарии (75)


  1. maxzh83
    06.04.2018 09:54
    -7

    «Фингерпринтинг» звучит как брейнфакинг


    1. marapper
      07.04.2018 00:36

      Пальцеотпечаток из кук хабра сотрите.


      1. alix_ginger
        09.04.2018 13:58
        +1

        Из печенек же


  1. mamont80
    06.04.2018 09:59
    +1

    Шикарная история. Ещё одной параноей по слежке прибавилось. И ещё добавлю что от этих скрытых символов сложно избавиться, как, например, от форматирования. Если вставить в блокнот, потом снова скопировать, то символы сохранятся, а форматирование нет.


    1. Sabin
      06.04.2018 10:08

      Вариант для чужого офисного компьютера: вставлять в word с включённым отображением всех знаков


      1. Mikhael1979
        06.04.2018 10:32
        +1

        Вариант, работающий на 146%: перенабрать текст вручную (или использовать OCR).


        1. GennPen
          06.04.2018 10:44

          Либо использовать стандартный блокнот. При сохранении текста с кодировкой ANSI он выдаст предупреждение, что используются Unicode символы, и все скрытые непечатаемые символы улетают в трубу.


          1. DrZlodberg
            06.04.2018 10:52

            Подменять иногда рус на лат символы с одинаковым начертанием. Фиг кто заметит при беглом просмотре.


            1. GennPen
              06.04.2018 10:59

              Word выделяет такие слова как ошибочные.


              1. DrZlodberg
                06.04.2018 11:04

                Об этом не подумал. Но блокнот, вроде не проверяет. Хотя ворд периодически выделяет и правильные, слишком большое количество может быть подозрительным. Для больших текстов можно иногда добавлять второй пробел. Собственно в случае с большими текстами можно придумать массу синтаксически корректных замен, которые не спалить. Автоматически их делать для пары десятков вариантов тоже не проблема. Собственно идея давать различный текст подозреваемым была придумана не одну сотню лет назад.


                1. bopoh13
                  06.04.2018 11:38

                  <nerd>Только это был не текст, а словесная информация.</nerd>


                  1. DrZlodberg
                    06.04.2018 12:00

                    Что есть «словесная» информация? Речь была об кусках теста с сайта (причём много их, как я понял), т.е. вполне подходит.
                    Формально — любая читаемая информация — текст. Даже числа и любые знаки. В т.ч. даже невидимые, как, собственно, в самой статье.


                1. LoadRunner
                  06.04.2018 12:31

                  Для больших текстов можно иногда добавлять второй пробел.
                  Лишний пробел довольно легко заметить в тексте, даже не читая его, просто при беглом просмотре. Если только он не попадает на конец строки.


                  1. DrZlodberg
                    06.04.2018 12:56

                    Даже если так — кто его заподозрит? И тем более будет исправлять. Обычно такие тексты копируют по принципу «синтаксис и пунктуация автора сохранены», сиреч — не глядя. Опечатки тоже обычно не правят. Собственно тексты без ошибок (особенно для внутреннего пользования) сейчас не редкость, и мало кто обращает на это внимание. Или вместо обычных использовать неразрывные.
                    Добавить пару пробелов в уникальной для юзера комбинации и всё. А для длинных текстов и небольшого количества клиентов — даже одного. Даже если кто придерётся, что текст кривой — всегда можно сослаться на залипший пробел (кстати при перекосе пробела на старой клаве такое случается, как и при слишком задранной скорости автоповтора).


            1. GeneAYak
              07.04.2018 04:36

              Вообще-то суть не в том, чтобы показать, что текст скопировали. А именно уличить того, кто его копирует. Смысл просто менять букву или пробел добавлять?


              1. DrZlodberg
                07.04.2018 09:20

                Вообще-то пробел можно добавлять в разные места, в уникальной для юзера комбинации. Потом просто по его положению можно узнать, какая из версий ушла. То, что текст скопирован известно уже по условию.


                1. ainoneko
                  07.04.2018 18:37

                  Дополнительная программа будет вставлять пробелы в случайные места, чтобы подставить кого-то другого?


                  1. DrZlodberg
                    07.04.2018 19:37

                    Каким образом?
                    Чтобы подставить кого-то другого нужно как минимум:
                    1. Знать о том, что эта система вообще существует (т.е. это должен быть кто-то из очень своих)
                    2. Знать о том, какая комбинация кому соответствует (т.е. это должен быть кто-то из админов)
                    Собственно в любой случае тут уже не сработает никакой из вариантов предложенных в статье или комментариях.


                1. fantast100
                  08.04.2018 12:34

                  Вобще-то пользователей может быть больше, чем комбинаций.


                  1. DrZlodberg
                    08.04.2018 12:55

                    Прикинем приблизительно. Текст 100 слов (очень короткий):
                    один пробел: 100 вариантов.
                    2 пробела: ~10000
                    Опечатка (например довольно типичная — замена 2х соседних букв местами): ~300..400
                    Опечатка (замена символа): ~6000..7000
                    Подсчёты крайне приблизительные, но порядок прикинуть позволяют.
                    И 100 слов — это очень мало. В этом комментарии их примерно 40.


        1. DrZlodberg
          06.04.2018 10:50

          Не. При желании можно, например, делать рандомные ошибки в словах. Потом по анализу можно поймать.


          1. Keyten
            06.04.2018 18:50

            Можно использовать разные типы кавычек, разные виды тире / дефисов / дефисоминусов / разделителей в телефонном номере / etc. Это ещё незаметнее.

            И можно даже пойти ещё дальше и заменять слова на синонимы.


      1. DrZlodberg
        06.04.2018 10:46

        На самом деле тут можно предложить и менее палевный вариант. Например подменять символы на подобные по начертанию, но из других кодовых страниц (можно спалить шрифтом, у которого начертания отличаются) или псевдорандомно вставлять обычный/неразрывный пробел (при некоторой внимательности можно заметить). Оба варинта вполне пройдут через блокнот и ворд (вроде неразрывные он не отличает от обычных при показе)


        1. FillCT
          06.04.2018 14:03

          в ворде неразрывный пробел отличается от обычного, при включении непечатаемых символов сразу заметен.
          Если текст направлен ограниченному количеству человек, можно вставить в середине предложение, в котором будут меняться синонимы слов в зависимости от пользователя. Затем по синонимам вычислять id пользователя. Еще лучше пораскидать таких слов по всему тексту в «случайном» порядке.


          1. DrZlodberg
            06.04.2018 14:48

            Ну как вариант я подобное и предлагал. Синонимы — муторно и требует ручной работы. Да и работает только для ну очень ограниченного количества. Проще заменить какие-либо часто встречающиеся обороты или слова. Это можно делать и автоматически. Ну и чем больше их в тексте — тем, очевидно, больше возможных комбинаций.


      1. sumanai
        06.04.2018 11:34

        Firefox тоже подчёркивает. Плюс прямо на странице он разрывает слово, если нужно перенести, поэтому я подвох заметил сразу.


    1. 0mogol0
      08.04.2018 12:33

      Я уже давно думал, что для отслеживания эл.книг можно использовать лишние / опциональные знаки препинания, например, заменять точку запятой, или запятую на точку с запятой. Если выделить десятка два-три таких мест (а лучше сотню, для дублирования), то можно каждой продаваемой книжке присваивать свой индивидуальный код, а дальше смотреть, кто из покупателей выложил книгу на флибусту. Чтобы найти все такие места потребуется не один экземпляр купить.


  1. LukaSafonov
    06.04.2018 10:03
    +2

    Схожие методы использовались на «околохакерских» форумах для идентификации каналов утечки информации.


    1. questor
      06.04.2018 19:51

      Это вы ещё не вспомнили 'вариант омега' про радиоигру разведок: помните точку в конце предложения?


      1. Vkuvaev
        09.04.2018 11:08

        Это, если не ошибаюсь, история о том, как британцы, судя по всему, не без помощи инсайдера, спалили кучу своих агентов в европе супротив германской разведки. Агенты должны были помечать точкой(или отсутствием), что раскрыты, и они это делали, но руководство проигнорило, и на них полагались как на надежных. В итоге в «надежную» точку досылали людей на погибель…


  1. stepanovmm
    06.04.2018 10:46
    +1

    Например, вы можете предположить, что ваш терминал попытается их отобразить (мой нет!).

    Н<200b>апример, в э<200b>то пред<200b>ложение я вст<200b>авил де<200b>сять про<200b><200b>белов н<200b>улевой ширины, вы эт<200b>о замет<200b>или?
    Для тех кому интересно(Vim).


    1. mayorovp
      06.04.2018 10:50
      +4

      Еще вот так их можно найти (если знать что они там есть!):


      Двойной клик выделяет кусок текста, ограниченный пробелами.


      1. a1ien_n3t
        06.04.2018 11:10

        Хмм firefox выделяет все слово…


        1. griba
          08.04.2018 12:34

          firefox при попытке поиска «в это» говорит, что ничего не нашел


      1. Evgenym
        06.04.2018 11:42
        +1

        Вчера как здесь читал про дополнение для Chrome, которое находит такие символы в тексте. Называется «Replace zero-width characters with emojis».
        image. Похоже, статья перекликается с этим переводом.


      1. Serj_By
        06.04.2018 12:02

        Чтобы избавится от этого недостатка, достаточно вставлять их до/после пробелов. Правда, текст для этого должен быть достаточно длинным.


    1. Bringoff
      06.04.2018 12:08

      Стандартный маковский тоже вполне справляется:


      Скрытый текст


    1. lBaltazar
      08.04.2018 12:34

      Edge прекрасно показывает все «пробелы».

      image


      1. mayorovp
        08.04.2018 18:13

        Это не Edge пробелы так показывает, это они в комментарии так записаны были…


  1. t0rr
    06.04.2018 11:10

    Радует то, что в мессенджерах пересылка таких копипастов не работает.

    Например, вот так выглядит «скрытая» информация в Telegram:
    image

    Эффект блокнота :)


    1. cruzo
      06.04.2018 12:00

      Зато в веб-версии Телеграма все прекрасно работает:
      image


    1. 403
      06.04.2018 12:11

      Desktop, Linux:
      Telegram Desktop, Linux


  1. ionicman
    06.04.2018 11:28

    Боже, зачем так сложно-то?
    Во-первых любой нормальный rich-edit это покажет, во-вторых (вытекающее из первого) — ненадежно — символы могут быть потеряны при копировании или очистке и т.д.

    Кодирование есть куда проще — знаками пунктуации. Тире и дефисов в юникоде штук 5, замена точек на точку с запятой и т.д.

    Имея 5 вариантов — это уже 5 бит — 2^5 пользователей.

    Никто на это не обратит внимание, как на похожие по начертанию символы или что-то еще. Все привыкли, что типографика всегда страдает.


    1. Loki3000
      06.04.2018 11:43

      Имея 5 вариантов — это уже 5 бит — 2^5 пользователей.

      Ух ты! Целых 32 пользователя!:)


      1. exehoo
        06.04.2018 12:28

        Это на одних только тире и дефисах уже целых 32 пользователя, а если добавить многоточий, кавычек, апострофов…


    1. saluev
      06.04.2018 13:44

      Не понял вашу комбинаторику.

      Если у тире пять вариантов, то одно тире в предложении даёт возможность идентифицировать 5 пользователей, два — 25 и так далее.

      Но если тире в тексте больше одного, то их подозрительное различие будет визуально заметно. То же с пробелами разной ширины.


      1. ionicman
        06.04.2018 14:20

        Имелось ввиду, что использовать символы там, где они и должны быть использованы. Даже в небольшом тексте практически всегда есть тире — вот их и использовать, только код символа использовать один из пяти.

        Кроме того, можно составить текст так, чтобы там были по смыслу определенная типографика, а дальше — играться.


  1. lostpassword
    06.04.2018 11:38

    Так удалось вычислить инсайдера или нет?


    1. Loki3000
      06.04.2018 11:41
      +1

      Так удалось вычислить инсайдера или нет?

      Если дочитать статью до конца, то вопрос отпадет.


      1. lostpassword
        06.04.2018 11:41

        Почему-то не заметил то предложение. Спасибо!


        1. super-guest
          07.04.2018 03:06

          Чего уж там, я тоже не дочитал до конца :)


        1. achekalin
          07.04.2018 08:58

          Концовка мягковато описана. С учётом "любви к нему" и усилий по вычислению, я прямо ждал ту картинку "он не сделал бекап и дропнул базу", ну или хотя бы что-то более суровое ("нашли его с группой товарищей и заставили вслух читать число пи до 1000 знака!"), чем просто забанили.


  1. Alexus819
    06.04.2018 12:46

    Н? апример, в э? то пред? ложение я вст? авил де? сять про?? белов н? улевой ширины, вы эт? о замет? или?
    стандартный Windows cmd.exe


  1. ooprizrakoo
    06.04.2018 13:39
    +1

    Много лет назад, когда писатели-фантасты были гораздо ближе к фэндому, они давали свои первые версии романов своим знакомым (распространяя через фидо и затем интернет).
    Однако для того, чтобы обезопаситься от утечек, многие из них каждому адресату отправляли тексты романов с некоторыми уникальными изменениями — лишний пробел между словами, запятая сдвинутая вправо, использование буквы «ё» там, где у других буква «е», и всё такое прочее. Не сказать, что утечки были массовой проблемой, но возможно в т.ч. потому, что получатели знали о возможном «фингерпринтстве», а инсайдеры более одного раза не могли предать чужое доверие.


  1. TyVik
    06.04.2018 15:32

    deleted


  1. domix32
    06.04.2018 17:06
    +1

    SPOON SPOON SPOON


  1. nevzorofff
    06.04.2018 18:19
    +3

    Сделать скриншот и публиковать его, а не копипасту. Можно ещё немного размыть или снизить разрешение, чтобы что-то невидимое для глаз исказилось.
    Так многие и делают, особенно на мобилах, бо скриншот — одно нажатие кнопок, а копипаста — та ещё затея.


  1. Keyten
    06.04.2018 18:23
    +1

    Кстати, стоило бы делать так:

    const zeroWidthSpace = '?';
    const zeroWidthNonJoiner = '?';
    const zeroWidthJoiner = '?';
    const zeroWidthNoBreakSpace = '';
    
    const binaryToZeroWidth = binary => (
      binary.split('').map((binaryNum) => {
        const num = parseInt(binaryNum, 10);
        if (num === 1) {
          return zeroWidthSpace;
        } else if (num === 0) {
          return zeroWidthNonJoiner;
        }
        return zeroWidthJoiner;
      }).join(zeroWidthNoBreakSpace);
    );
    


    1. sasha1024
      06.04.2018 18:30
      +4

      А ещё лучше:

      const zeroWidthSpace = '\u200B';
      const zeroWidthNonJoiner = '\u200C';
      const zeroWidthJoiner = '\u200D';
      const zeroWidthNoBreakSpace = '\uFEFF';
      


  1. sasha1024
    06.04.2018 18:23

    Мне для отображения символов в строке нравится qaz.wtf.

    По идее, таких сервисов в вебе должно быть навалом, но я почему-то нашёл только этот.

    Если кто-то знает лучший инструмент (веб- или командной строки Линукс) — буду рад услышать.


  1. tutam
    06.04.2018 20:18

    Попробуйте в демке стереть скопированный текст. Ничего не заметили?


  1. Sly_tom_cat
    06.04.2018 23:34

    На сколько я помню этих символов нулевой длинны немного больше чем 2…
    Плюс, как уже заметили выше есть еще одинаковые символы в разных языках.
    Т.е. даже если применять преобразование бинарного в… то гораздо оптимальнее преобразовывать в 4-, 8-, 16-ричный код (используя больше символов). Так меньше символов на тот же объем информации потребуется.


  1. bogolt
    07.04.2018 00:11

    Вставил в консоль:


  1. youngmysteriouslight
    07.04.2018 01:39

    Заметил раньше, чем первое предложение начал читать.

    Подумал, что косяк переводчика, но нет, на хромиумовских браузерах таки пробела не видно.


  1. vesper-bot
    07.04.2018 09:30

    Мораль: если копипастишь, вставляй вначале в Notepad!


  1. IvanTamerlan
    07.04.2018 19:22
    +1

    Ожидал после такой эпичной завязки игры шпионов продолжения в том же стиле, а не достаточно скучным и простым баном в качестве очень быстрой развязки после кульминации, когда шпиона вычислили.
    Нашел инсайдера, который сливает данные? Просто прекрасно, теперь можно управлять сливаемыми данными! Т.е. тупо отправлять дезу, периодически проверяя, что на других сайтах именно деза с правильным отпечатком имени. И теперь начинается настоящая шпионская игра! Особенно для того, чтобы инсайдер не заметил изменения отношения и «все осталось как есть» (с доступом к архиву правильных записей, как вариант).


  1. levder
    08.04.2018 12:33

    Объясните по подробнее пожалуйста.
    Вот это условие на первый взгляд вообще лишено смысла

     if (char === '?') {
          return '1';
     } else if (char === '?') {  
          return '0';
      }
    


    1. sumanai
      08.04.2018 14:01

      Там символы в кавычках разные, что очевидно.


  1. wxzarm
    08.04.2018 12:33

    Я действительно удивился тому, что введенной мной значение было отображено. Почему-то мне казалось, что в браузере Google Chrome данная проблема уже давно исправлена (хотя что-то мне подсказывает, что я что-то путаю).


  1. xinetus
    08.04.2018 12:33

    Регулярные выражения спасут копипаст ;).

    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="Keywords" content="refining" /><meta name="abstract" content="refining" /><meta name="description" content="refining" /><meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>Чистильщик</title>
    </head>
    <body style="text-align:center;margin:0;">
    <div>
    <textarea id='trash' type="text" style="width:90%;height:400px; text-align:center;"></textarea>
    </div>
    <button style="width:180px;height:60px;font: bold 20px/1.5 cursive; text-align:center;" id="_button">старт</button>
    <br/><br/>
    <div id="resultation"></div>
    <script>
    function refining(){
    	rG1='';
    	trash=String(document.getElementById('trash').value);
    	var sG1=new Array();
    	for(i=0;i<trash.length;i++){sG1[i]=trash[i].replace(/[^а-яА-яa-zA-Z_0-9-—!"№%?*()\[\]+=@#$%^&*{}:;"'?><.,|\ \\\/\n\	]/g, '\-');};		
    	for(i=0;i<sG1.length;i++){rG1+=sG1[i];};
    	document.getElementById('resultation').innerHTML=rG1;
    };
    document.getElementById('_button').onclick=refining;
    </script>
    </body>
    </html>
    


  1. VladislaWoW
    08.04.2018 12:33

    Такие пробелы нулевого размера и другие скрытые символы можна обнаружить еще на стадии копирования, с помощью обычной консоли браузера.


  1. denis_skripnik
    08.04.2018 12:33

    У этого метода есть значительный минус. При использовании программ экранного доступа, которыми пользуются незрячие, эти символы видны, их можно удалить или изменить при копировании.
    Также такой текст очень неудобно слушать. Вот прочитайте написанный в посте текст вслух: так он и читается скринридером:
    «Н апример, в э то пред ложение я вст авил де сять про белов н улевой ширины, вы эт о замет или?»

    P. S. Сам символ озвучивается при посимвольном чтении, как «Пробел нулевой ширины».


  1. retimer
    08.04.2018 12:33

    А дать ограниченному кругу пользователей вообще разный текст — не рассматриваем? Зачем мудрить со скрытыми символами? Задача в том, чтобы найти подлеца, а не в написании кучи скриптов…


  1. Solovej
    08.04.2018 13:21

    Занятная вещица, особенно учитывая если работаешь под TOR сетью, толку от TOR сети нет если ник светится.
    Получается надо текст писать картинкой и тогда есть хоть какой то вариант не спалится, хотя и с картинкой можно опростоволоситься.


    1. Solovej
      08.04.2018 17:16

      Было бы не плохо вставить ссылку в конце статьи на add-on для chrome, которое предупреждает о наличии таких символов.