Матановая капча на PHP — это просто!


    В этом топике я хочу вам рассказать о создании т.н. "матан-капчи" с использованием только PHP и GD. Для отрисовки формул будем использовать PhpMathPublisher — свободно распространяемую библиотеку, использующую только расширение GD.

    Немного теории


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

    Собственно, разработка


    PhpMathPublisher должен лежать в папке phpmathpublisher.
    Инициализируем:
    
    include("phpmathpublisher/mathpublisher.php"); // Подключаем рисовалку формул
    $upper=rand(0, 10); // Верхний предел интеграла
    $lower=rand(-10, 0); // Нижний предел интеграла
    $num=4; // Количество слагаемых в функции
    

    Теперь нужно создать строку с формулой, можно одновременно посчитать ответ:
    
    $text="int{".$lower."}{".$upper."}{";
    for($i=0;$i<$num;$i++){
      $k=rand(1, 5); // Коэффициент перед x
      $p=rand(1, 5); // Показатель степени x
      $sign=rand(0, 2)==0?0:1; // Знак, плюс будет в 2 раза чаще
      $tt=$k>1?$k:""; // Временная переменная для хранения слагаемого
      $tt.="x";
      if($p>1)$tt.="^".$p;
      if($i==0){
        if($sign==1)$text.="({-}".$tt.")";
        else $text.=$tt;
      }else $text.=($sign==1?"-":"+").$tt;
      if($sign==1)$k=-$k;
      $answer+=($k*pow($upper, $p+1)/($p+1))-($k*pow($lower, $p+1)/($p+1));
      // И заодно считаем ответ.
    }
    $text.="dx}";
    

    В итоге у нас получится строка такого вида:
    int{-4}{4}{3x^5-4x^5+3x^2+x^2dx}
    Теперь осталось отрисовать всё это на картинке — с помощью PhpMathPublisher это займёт всего несколько строк:
    
    $formula=new expression_math(tableau_expression(trim($text)));
    $formula->dessine(24); // 24 - размер символов
    $w=imagesx($formula->image)+20; // Отступы по 10 пикселей с каждой стороны, иначе при применении искажений пределы у интеграла съезжают за край изображения
    $h=imagesy($formula->image)+20;
    $fi=imagecreatetruecolor($w, $h);
    imagefill($fi, 0, 0, 0xFFFFFF);
    imagecopy($fi, $formula->image, 10, 10, 0, 0, $w-20, $h-20);
    

    Дальше неплохо применить нелинейные искажения — для этого я использовал алгоритм MultiWave. По ссылке полный код и пример использования.
    А дальше нам ничего не остается, кроме как вывести полученную картинку в браузер:
    
    header("Content-type: image/png");
    imagepng($im);
    

    Вместо заключения


    Ещё несколько капч, сгенерированных этим скриптом:



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

    Подробнее
    Реклама
    Комментарии 127
    • +2
      Почему бы не пробовать также использовать задачи по физике с меняемыми параметрами или что-то подобное?) Типа, задачи про ванну и открытый кран и сливное отверстие).
      • 0
        Картинка слишком большая получится.
        • +1
          А с другой стороны организовать сервис для школьников, которые бы с удовольствием купили решение своё ДЗ / ТЗ и пошли бы доверстывать другие предметы/ доверстывать сайт/ изучать самый интересный низкоуровневый язык /
          играть в футбол/в кино казино/по бабам/по сайтам с ними / учить орфографию / нудеть за нее в карму на хабре /
          завоевывать мир / устраивать революцию / седеть в подполье как Ленин(если нет лысины)/ гамать / итд e.t.c.../
          Отличная монетизация, это не книжки распознавать.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +40


            популяция кого должна увеличиться в случае с CAPTCHA? %)
            • +10
              Ботов! Кого же ещё!)
              • +4
                Только не увеличиваться, а уменьшаться, как в неделю чумы.
              • +3
                локализаторы халтурят: за текстом виден английский оригинал
                • +1
                  можно еще добавить «ШОК!»
                • 0
                  популяция китайцев на сервисах по распознаванию каптчи
                • +1
                  Начнем отсчет не с воскресенья, а с понедельника :) Планирую к выходным запостить еще один топик на тему капчи.
                  • +1
                    Астрологи объявили неделю астрологов. Количество астрологов в комментах на хабре выросло раз в пять %)
                  • +6
                    Я в шоке.
                    • +5
                      Я знал что ты оценишь.
                    • 0
                      И даже видеокапчи никакой не надо.
                      • 0
                        Недостаток в том, что она слишком читабельна. Если распознать формулу, то автоматизировать ее решение очень легко.
                        • 0
                          Именно. Причем работает простая связка уже разработанных пакетов. Распознавание + любой пакет символьной математики (maxima, например, ибо работает из консоли).
                        • +2
                          Отличное решение для социальной сети математиков.
                          • НЛО прилетело и опубликовало эту надпись здесь
                            • НЛО прилетело и опубликовало эту надпись здесь
                              • +6
                                Зачем же только для математиков? Отличное решение для многих сайтов. Только упростить бы примеры чуть-чуть, чтобы они не очень далеко ушли от табличных.
                                Я бы на многие сайты с контентом 18+ такое вешал, на вход. Вышка — 1,2 курс, т.е. школьники не пройдут, студенты, которые плохо учатся, вместо мастурбации, будут учить матан, выучат и пройдут таки. Студенты 4,5 курсов, которые уже забыли как решать интегралы, в порносайтах не нуждаются, т.к. уже обзавелись более/менее постоянными партнершами.
                                Надо бы придумать капчу еще и с орфографией и пунктуацией. Вот тогда бы грамотность повысилась.

                                Жаль только что моя мысль утопична, ибо не охватывает возрастную аудиторию от 25, которые и матан забыли, и с зазнобой уже могли расстаться или вместе с ней же желают подобные сайты посмотреть.
                                • +3
                                  А еще могут встретиться студенты из гуманитарных вузов. Они будут обречены на неврозы и бесконечную сублимацию :)
                                  • 0
                                    Люди просто воспользуются Wolfram Alpha.
                                    • +1
                                      >>Вышка — 1,2 курс, т.е. школьники не пройдут,
                                      Странно, странно. Емнип интегралы проходят в 10м классе, какой первый-второй курс вышки?!
                                      • –1
                                        Сейчас уже в 11-ом. Это раз. А во вторых, там не уходят далее стандартной таблицы производной и свойства S(f(x) + g(x))dx = Sf(x)dx + Sg(x)dx
                                        • +1
                                          А в сабже задача сложнее?! o_0
                                          • 0
                                            Нет. Ну а что делать более младшим школьникам, если вдруг «приспичило» зарегестрироваться на подобносм сервисе? )
                                    • 0
                                      Китайцы будут в восторге! Решил задачку и не надо много печатать, и в институте не зря проучился
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                      • +8
                                        [зануда]Достаточно попробовать два варианта — true или false[/зануда] :D
                                        • +4
                                          Нужно добавить графу «Proof».
                                          • 0
                                            (мечтательно)(оффтопик)Кстати, было бы интересно написать реализацию какого-нибудь языка для записи математических логических доказательств (те-же кванторы, но для компьютерной клавиатуры) и реализовать проверку доказательств на истинность…
                                            • +3
                                              Таких систем уже существует, как минимум:

                                              Agda
                                              Isabelle
                                              Epigram
                                              Coq

                                              однако использование капчи с их применением было бы оправданным разве что на LtU
                                              • 0
                                                Ну, я подозревал, что существуют. Спасибо за ссылки. С другой стороны, интересно было бы написать такую для себя и самому :)

                                                Ладно, пора заканчивать этот оффтопик :)
                                        • 0
                                          42
                                        • +3
                                          У вас ошибка в решении первой капчи (знак не тот).
                                        • +1
                                          Это ж надо так ненавидеть людей:)

                                          Just for fun или Just for adequate users?
                                        • –5
                                          фак и тут матан…
                                          • +11
                                            ида dx применяется ко всему подинтегральному выражению соответственно неплохо бы его взять в скобочки…
                                            • 0
                                              подинтегральное выражение.
                                              • –2
                                                вовсе необязательно. Знак интеграла и дифференциал вполне играют роль ограничителей
                                                • +7
                                                  Вообще-то из свойств дифференциала и определенного интеграла этот дифференциал — вполне себе сомножитель, а не формальность/ограничитель.
                                              • –7
                                                Откройте любой задачник по матану и убедитесь, что этого никто никогда не делает
                                                • +6
                                                  Сам всегда так делаю, потому что это правильно, а в случае с интегралами по поверхностям так вообще необходимо. dx – это не просто формальность и «ограничитель».

                                                  Но я последовал вашему совету и открыл Демидовича: Что я сделал не так?
                                                  • –1
                                                    А я и не говорил, что dx — это формальность или «ограничитель»
                                                    Да, сам сейчас убедился. Просто привык видимо, что в основном решаем интегралы с дробями и, соответственно, dx выносят из дроби и скобки не нужны.
                                            • 0
                                              Можно ещё попросить решить алгебраически.
                                              Правда и это не поможет.
                                              Такие выражения может вычислять Maxima. Кроссплатформенное консольное приложение. Причём ответ может выдать даже в виде алгебраического выражения.
                                              • +1
                                                Это гениально, бессмысленно и беспощадно одновременно!
                                                • +5
                                                  image
                                                  • +3
                                                    Ну… конкретно этj уравнение простое — из-за arctg(x) подкоренное выражение стремится к нулю, а ответ, соответственно, к ln2
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • –5
                                                        Опередили… И, кстати, sin(1/x) никуда не «бегает», а активно стремится к нулю.
                                                        • +12
                                                          Ещё как бегает…
                                                          • –10
                                                            Бегает синус при стремлении аргумента к бесконечности. А в данном случае его аргумент к нулю стремится.
                                                            • +9
                                                              Там же х->0, поэтому (1/x)->к бесконечности.
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                • +3
                                                                  Вот черт, это я проглядел, дико извиняюсь. Ничтоже сумняшеся полагал, что аргумент стремится к бесконечности. Каюсь, грешен.
                                                      • +1
                                                        Позволю себе дополнить, что не только поэтому, а еще и потому, что предел синуса с бесконечно малым аргументом равен 0. Хотя в данном случае подошел-бы синус с любым аргументом, ибо синус — функция ограниченная. Но, в общем случае, произведение бесконечно малой ф-и на другую ф-ю бесконечно малой не будет. Вы уж простите мое занудство, но математика и вправду требует полноты.
                                                    • 0
                                                      Теперь упертые спамеры научатся применять Wolfram alpha
                                                      • +4
                                                        Тогда Wolframalpha просто поставит себе такую капчу.
                                                        • 0
                                                          Ну, alpha то для ленивых. mathkern из командной строки тоже не плох
                                                        • +13
                                                          image
                                                      • –2
                                                        Чему удивлятся? Я видел форму еще 4 года назад, когда нужно было примитивный интеграл взять :)
                                                        • 0
                                                          Что уж там многочлен, взяли бы интеграл, зависящий от параметра.
                                                          • +1
                                                            Срочно нужна гениальная идея, которая позволила заменить ети капчи… Это как заноза в структуре множества порталов, бестолковое действие для пользователя: когда вокруг вроде столько гениальных и простых идей капча на их фоне смотрится как временное решение, которое осталось на постоянку. Какие есть альтернативы или принципиально отличные обходные пути?

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

                                                            Кратко моё мнение таково: защита от ботов не должна строится на сложности решения плохо формализуемых задач (распознание текста, голоса). Со временем ЭВМ научится их решать не намного хуже человека. А вот на чём эту защиту построить (и нужна ли она вообще), это я не знаю, но кой-какие идеи есть. Надо мыслить на уровень выше, я чувствую идею, она рядом, рядом…
                                                            • +1
                                                              Извиняюсь за тся (ох уж это правило, как бы я его твёрдо не знал, всё равно на автомате делаю ошибки) и назойливое «капча».
                                                              • 0
                                                                как бы я его твёрдо не знал

                                                                Вам бы ещё правила с не/ни подучить…
                                                          • +17
                                                            Напомнило…
                                                            • +2
                                                              К слову, кто помнит, кто изображен на снимке? Это фотография Тарасевича, работа называется «Поединок», но вот информации о запечатлённом учёном в сети, кажется, нет.
                                                            • +1
                                                              Есть пара проблем:
                                                              1. Как вы предлагаете вводить ответ? например 1/3? в виде дроби? как вариант — просить ввести только целую часть.
                                                              2. Несмотря на показную сложность, матан-капчи куда проще чем обычные. Для вычисления используются простенькие шаблоны.
                                                              • 0
                                                                > Как вы предлагаете вводить ответ?
                                                                Перейдите по ссылке в конце поста.
                                                                • 0
                                                                  +1. Они как правило по пр. Лопиталя ситаются на раз.
                                                                  • 0
                                                                    Это в случае пределов естсственно
                                                                  • +1
                                                                    Приложить в качестве ответа сканированную картинку с решением от руки. Модератор в течении суток проверяет решение и, если оно верно, активирует аккаунт.
                                                                    • 0
                                                                      У меня нет сканера и фотоаппарата. Платить деньги чтобы отсканить, идти куда-то, отправлять решение. Оно мне надо? )
                                                                      • 0
                                                                        Ну тогда заказным письмом.
                                                                        • 0
                                                                          И тогда не сутки ждать а неделю минимум))
                                                                          • 0
                                                                            Лучшая каптча тогда получается на gosuslugi.ru
                                                                            • 0
                                                                              Ага. Я там так и не зарегался кстати, письмо не пришло, а потом забил.
                                                                        • +1
                                                                          image
                                                                    • –1
                                                                      Вообще, думаю, что пора бы уже изобрести более совершенный алгоритм отсивания роботов, нежели капча. Желательно не требующий от пользоватля дополнитльных телодвижений.
                                                                      • +1
                                                                        Когда роботы захватят планету, им придётся придумывать алгоритмы, которые будут отсеивать людей… Вот тогда-то они вспомнят эту статью!
                                                                        • 0
                                                                          Нет, роботы придумают другое. Например, надо будет в течении 5 секунд вычислить хэш из случайного числа и передать его в виде бинарного кода.
                                                                          • +4
                                                                            Будет что-то вроде ужасного сна Бендера 0101001 1001010 10011001 0000010 2 А! двойка! И просыпается смахивая холодный пот раскалившееся масло со лба.
                                                                            Жаль, блондинки не выживут.
                                                                        • 0
                                                                          Карма Ааап :)
                                                                          • +11
                                                                            побольше таких формул:
                                                                            • +4
                                                                              > «Вот пример решения для картинки из начала статьи:...»
                                                                              Да уж. Вижу с мат. анализом у Вас было не очень. Почему бы сначало не упростить выражение:
                                                                              image
                                                                              а потом уже решать его?
                                                                              • +3
                                                                                > Да уж. Вижу с мат. анализом у Вас было не очень

                                                                                а причём здесь мат. анализ, если для упрощения нужна обычная алгебра?
                                                                              • +1
                                                                                У меня на ICQ стоит фильтр с интегралом. Кто его берёт (интеграл), тот сможет мне написать. Очень удобно.
                                                                                • 0
                                                                                  А у меня стоит простенький предел, увы большинство не может решить даже его :)
                                                                                  • +3
                                                                                    У меня стоит вот такое выражение:
                                                                                    Сколько будет: 2 + один — two?
                                                                                    Пока что не один бот не пробрался, да и некоторые люди. ;)
                                                                                    • 0
                                                                                      Оригинально! Надо будет поюзать такую конструкцию. Спасибо за идею.
                                                                                      • 0
                                                                                        я б тоже не пробрался.
                                                                                        Что за знак между один и two? Минус или тире?
                                                                                        Если тире, то возможные ответы: no, false, нет…
                                                                                        Если минус, то: один, 1, one…
                                                                                        • 0
                                                                                          И, какой же все-таки правильный ответ?
                                                                                          а) один
                                                                                          б) one
                                                                                          в) 1
                                                                                          г)?
                                                                                          • 0
                                                                                            Там у меня еще пояснение стоит:
                                                                                            ответ запишите числом.
                                                                                            Поэтому ответ: 1.
                                                                                            • 0
                                                                                              Можете убрать пояснение, а в правильные варианты ответов внести «один, one, 1»
                                                                                              • 0
                                                                                                Как показывает практика лучше оставить пояснения.
                                                                                        • 0
                                                                                          А у меня — вопросы из БД вопросов «Что? Где? Когда?» :) Так интересно иногда читать варианты ответов потенциальных собеседников :)
                                                                                        • +4
                                                                                          $upper=rand(0, 10); // Верхний предел интеграла
                                                                                          $lower=rand(-10, 0); // Нижний предел интеграла

                                                                                          НЕТ! При больших выборках в одном случае из ста двадцати одного (=11*11) отрезок интегрирования будет от 0 до 0 по числовой оси, а это автоматически = 0, значит вы автоматически получаете взламываемость капчи не менее 0.82%, что есть УЖАСНО плохо. Лучше так:

                                                                                          $upper=rand(1, 10); // Верхний предел интеграла
                                                                                          $lower=rand(-10, -1); // Нижний предел интеграла

                                                                                          И вообще нуля не касаться!
                                                                                          • 0
                                                                                            Более того, каждый раз когда подинтегральная функция окажется симметричной относительно начала координат, то интеграл от нее по симметричному отрезку будет равен 0.
                                                                                            • 0
                                                                                              Это уже надуманная проблемы, потому что вероятность симметричности отрезка и многочлена одновременно на порядки меньше, чем 0.82%.
                                                                                              Да и проверять многочлен и отрезок на симметричность программно немногим проще, чем взять и посчитать этот интеграл.
                                                                                              • 0
                                                                                                > «вероятность симметричности отрезка и многочлена одновременно на порядки меньше, чем 0.82%.»
                                                                                                Давайте посчитаем.
                                                                                                Степени, которые предлагает автор 1 — 5. Нас устраивают степени 1,3,5.
                                                                                                Автор предлагает отрезки от -10 до 0 и от 0 до 10. Симметричных промежутков 11 из 121.
                                                                                                Итого вероятность для 4 слогаемых около 0,22%.
                                                                                                Так что не на порядки как видите.
                                                                                                • 0
                                                                                                  Да, я что-то махнул. Там даже больше, чем (3/5)^4 * (11/121) вероятность, потому что какие-то степени могут сократиться.
                                                                                                  • 0
                                                                                                    Да, там еще частные случае. Так, что все таки не надуманно.
                                                                                          • +1
                                                                                            А как насчет геометрической капчи? Найти, например, площадь трапеции по длинам оснований и высоте или периметр равнобедренного треугольника?
                                                                                            • +1
                                                                                              Или какоенибуть простенье уравнение:
                                                                                              image
                                                                                              • +2
                                                                                                Это такой тонкий подвох? Чтобы люди думали, как записать пустое множество?
                                                                                                • +1
                                                                                                  В множестве комплексных чисел ответом является не пустое множество.
                                                                                                  • +1
                                                                                                    Вот прямо про это первым делом народ и подумает, я уверен.
                                                                                                    Да и как вы предлагаете писать ответ для этого «простенького» уравнения? ± i * arccosh(Pi/3)? Ясно же, что идея дохлая.
                                                                                                    Или вы всё-таки опечатались выше и имел в виду что-нибудь другое.
                                                                                                    • 0
                                                                                                      Это такой тонкий подвох :-)
                                                                                                  • –1
                                                                                                    Наверно, имелся в виду arccos
                                                                                              • 0
                                                                                                Даже такие объекты используют рекаптчу, зачем нам новое: habreffect.ru/files/eb8/c3d5f2d6e/captcha2.jpg
                                                                                                • –5
                                                                                                  Вам не кажется, что это уже черезчур! Такую капчу можно вводить только, если вы хотите избавиться от своих пользователей! Потому, что нормальный юзер просто уйдет с этого сайта, а ботов будут учить матану…
                                                                                                  • +2
                                                                                                    Не учишь матан — пойдешь на метан (с) Л.
                                                                                                    Так и знал что будет хотя бы один такой коммент. Баттхерт, что решить не сможешь? Или не понятно, что такая каптча будет использоваться в специализированных серисах, а не во всяких соцсетях?
                                                                                                    • 0
                                                                                                      Нам такие юзеры не нужны :)
                                                                                                    • 0
                                                                                                      Я тут на одном из форумов радиолюбителей видел схему усилителя НЧ вместо капчи и предложение подобрать спротивление R2 при некоторых условиях :)
                                                                                                      • 0
                                                                                                        Это капча для военкомата?
                                                                                                        Я хабровскую то с трудом прохожу =)
                                                                                                        • 0
                                                                                                          Дошутились (http://habrastorage.org/storage/7ef04c2f/65b3b17a/8b320fa7/0ff9e1ef.jpg)
                                                                                                          • 0
                                                                                                            Ну не показывает картинку =(
                                                                                                            habreffect.ru/files/624/cd04c4705/128790507478467.jpg
                                                                                                            • 0
                                                                                                              охренеть, я учил матан 10 лет назад, уже и на бумажке не посчитаю
                                                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                • +2
                                                                                                                  если у него гуманитарное образование — это хуже бота, зачем он сдался?
                                                                                                                • 0
                                                                                                                  Оффтоп: Может кто знает, есть ли что-то похожее для ruby(в смысле гем для генерации графических изображений математических выражений)?
                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь

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