Определяем «неправильные» слова при борьбе со спамом

    При борьбе со спамом на форуме возникла идея автоматически отлавливать слова, внешне похожие на «нормальные», но фактически отличающиеся от шаблонных, имеющихся в базе стоп-слов. Делается это путём замены кириллических символом на латиницу и наоборот. Например, «Пpoдaeм бeтoн» и «Продаем бетон» только внешне выглядят одинаково, а на самом деле они отличаются друг от друга.
    Вот я и написал небольшую функцию для уменьшения энтропии Вселенной, которая определяет (если сможет) язык, на котором написано слово, и заменяет его на нормальное. Затем проверяем это слово по списку стоп-слов и принимаем решение, запрещённое оно или нет :)

    (Красным цветом помечается кириллица, синим- латиница или цифры)

    В подробности кода на C# вдаваться не буду, думаю, что всё будет понятно.
    Конструктивным предложениям и замечаниям буду рад :)

    public string CheckWord(string word, out string lang, out bool Changes)
    {
      lang = "?";
      string newword = word;
      string OnlyRu = "БбвГгДдЁёЖжЗзИиЙйЛлмнПптУФфЦцЧчШшЩщЪъЫыЬьЭэЮюЯя";<br>
      string OnlyEn = "DdFfGghIiJjLlNQqRrSstUVvWwYZz";
      string Rus = "АаВЕеКкМНОоРрСсТуХхЗО1тиа@пь";
      string Eng = "AaBEeKkMHOoPpCcTyXx30imu@anb";

      bool IsRu100percent = false;
      foreach (char c1 in word)
        foreach (char c2 in OnlyRu)
          IsRu100percent = IsRu100percent || (c1 == c2);
      
      if (IsRu100percent)
      {
        lang = "ru";
        
        //Конвертируем все сомнительные символы в русские
        for (int i = 0; i < word.Length; i++)
          if (Eng.IndexOf(word[i]) >= 0)
          {
            //помечаем word[i] как "фальшивый"
          }
        for (int i = 0; i < Rus.Length; i++)
          newword = newword.Replace(Eng[i], Rus[i]);
      }
      else
      {
        bool IsEn100percent = false;
        foreach (char c1 in word)
          foreach (char c2 in OnlyEn)
            IsEn100percent = IsEn100percent || (c1 == c2);
        if (IsEn100percent)
        {
          lang = "en";
          //Конвертируем все сомнительные символы в английские
          for (int i = 0; i < word.Length; i++)
            if (Rus.IndexOf(word[i]) >= 0)
            {
              //помечаем word[i] как "фальшивый"
            }
          
          for (int i = 0; i < Eng.Length; i++)
            newword = newword.Replace(Rus[i], Eng[i]);
          
        }
      }
      //Были ли замены?
      Changes = newword != word;
      newword = newword.ToLower();
      _SelectionColor = lang == "ru" ? Color.Red : lang == "en" ? Color.Blue : Color.Black;
      return newword;
    }

    * This source code was highlighted with Source Code Highlighter.



    Вызов происходит просто:
    string lang;
    bool changes;
    string re = "[\\w\\@]+";
    Regex rx = new Regex(re, RegexOptions.IgnoreCase | RegexOptions.Singleline);
    Match m = rx.Match("Пpoдaeм бeтoн");
    while (m.Success)
    {
      string newWord = CheckWord(m.ToString(), out lang, out changes);
      m = m.NextMatch();
    }

    * This source code was highlighted with Source Code Highlighter.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 32

      +1
      Оно конечно хорошо, но как это использовать в реальной жизни?
      В голову приходит только написание какого-нибудь плагина для аутглюка, который будет делать предварительное преобразование неправильных слов в правильные во входящих письмах до срабатывания фильтра на ключевые слова…
        0
        можно написать PS-скрипт для Exchange, например.
          0
          А еще в фильтр комментов к разным блогам можно!
          На php, как я понял, портировать ее просто.
          0
          для большей применимости в реальной жизни, программу надо бы сделать консольной. И под *nix порт нужен, т.к. большинство релеев крутится под *nix.
            +14
            Для большей применимости — я дал код функции. Хотите, в консоль делайте, хотите — в dll, хотите — переводите в *nix, на питон, на php… Я просто показал идею.
            Оконный вид программы с подсветкой слов — исключительно для наглядности работы функции.
              +1
              Что ж, спасибо за идею.
            +2
            К сожалению, это только один из многих частных случаев.
            В_И_А_Г_Р_А
            Виа(гра)
            ВИ/\ГР/\
            Не говоря уже о том, что много спама валит без прямого указания там ключевых слов.

            Пока компы не научатся понимать смысл текста (читай: пока не будет создан ИИ), спамеры всегда смогут придумать как обойти подобные фильтры.

            Но все равно спасибо, что занимаетесь этой темой. Надо держать спамеров в тонусе :)
              +2
              Вряд ли кто-то серьезно рассчитывает создать абсолютный фильтр. Спасает так называемый «барьер» — небольшие усилия помогают отстеять огромную массу любителей-спамеров. Дальше повышать барьер сложнее и процент отсеянных спамеров увеличивается намного медленнее. Главное — решить, где остановиться.

              На примере: фильтровал я как-то комментарии на сайте развлекательной тематики. Простой список стоп-слов позволили заблокировать процентов 90 нарушителей. После того как я перед проверкой стал удалять все символы кроме букв и цифр (тем самым отсекая варианты типа «В_И_А_Г_Р_А» или «Виа(гра)»), стало отсеиваться 98%. Остальные проверки были совсем специфическими и добавлялись на конкретные случаи, под настроение. В принципе, это — вариант, на котором можно остановится, все остальное пока проще изредка вычищать вручную.
              +1
              Капитан компилятор сказал что у переменной string OnlyRu в конце не стоит ";"
                +2
                Спасибо, поправил.
                  +1
                  А его друг другой капитан когда присмотрелся сказал что 6 похоже на русскую «б»
                    +2
                    Можете сами дополнить словарь по своему усмотрению.
                    Ещё подскажу: «m» похожа на маленькую русскую «т», но это, как и «6»-«б» бросается в глаза.
                      +1
                      Спамеры вконтакте спокойно используют «k» вместо «к», и не стесняются.
                        0
                        k и к как и З и 3 точно так же бросаются. Однакож отмечены в сабже. Зато тот кто будет машинально копировать из поста будет иметь «большую» защиту только не знаю от чего)
                          +4
                          Добавил «1тиа@», «imu@a» и убрал k/к из 100%-алфавита.
                          И обновил скриншот
                            0
                            Добавил тему в избранное чтобы был справочник сопоставления букв)
                              +2
                              Вообще, надо бы расширить функцию на работу с двусимвольными комбинациями.
                              Например, «bl» = «Ы», "/\" — «Л»
                                –1
                                Сделай просто массив, а не стринг.
                  +2
                  Хм, а почему бы не забраковывать письма в которых есть более некоторого количества слов, в которых используется вперемешку латинские и русские буквы?
                  Собственно сам факт того что в слове из 5 букв русского алфавита есть две буквы из латинского уже определяет то что слово — паразит.
                    0
                    Помоему наиболее разумное решение. Как минимум внимания таким письмам должно больше уделяться.
                    +1
                    спасибо. я сам хотел написать такой код, но руки не доходили. На моей работе это нужно не для спама, а для проверки написания товара. У нас блондинки умудряются завести в базе 1С товар вперемежку. Например, есть модель CT-404 (буквы англ.), а заводят русскими. А если CN-102, то первую букву напишут русской, а потом, так как в русской раскладке буквы N нет, то переключаются на английскую раскладку и вводят уже второй символ. Бардак в базе был еще тот.
                      0
                      Кстати, отсеять практически весь «нигерийский» спам можно всего лишь по одному (или трем) ключевым словам, практически не встречающимися в нормальных текстах — это «kin» или «next of kin» (наследник).
                        –2
                        Нигерийский спам самый нигерийский спам в спаме)
                        +1
                        Зря вы так на тему спам-фильтров: наивный байсековский фильтр и фильтр на основе метода Фишера (SmapBayes, подключаемый к Outlook как раз на основе Фишера) могут и используют признак смешение букв из разных алфавитов как признак спама, хотя затем можно нормализовывать текст по описанному выше методу и подвергать другим тестам: ключевые слова и словосочетания, регистр слов (к примеру, все буквы в верхнем регистре и таких «кричащих» слов множество), анализ метаинформации: кто отправил письмо, откуда и т.д… Если же сразу нормализовывать текст, то можно потерять множество признаков, по которым мог бы обнаружен спам.

                        А за наглядный пример нормализации текста спасибо.
                          –3
                          Спамеры такие спамеры
                            –1
                            Можно еще считать слова с подменой букв как заведомо спамерские.
                              0
                              Я ещё проще придумал. Если в слове происходит смена кодировки, то это спам!
                                0
                                Кодировки???
                                Уж не языка-ли?
                                0
                                за этот файл похожих символов юникода два года назад я получил 500 руб. от своего друга
                                narod.ru/disk/18479522000/!likes.xml.html
                                  0
                                  Вам спасибо, а парсер лох (: j.mp/likess )
                                  +2
                                  Ещё немного изменил строчки:
                                  string Rus = «АаВЕеКкМНОоРрСсТуХхЗО1тиа@пь930»;
                                  string Eng = «AaBEeKkMHOoPpCcTyXx30imu@anbgEo»;

                                    0
                                    CEO vs СЕО

                                    Only users with full accounts can post comments. Log in, please.