0,0
рейтинг
6 июня 2011 в 00:48

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

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);

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


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



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

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (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
      Спасибо, поправил.
  • +1
    Это ж надо так ненавидеть людей:)

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

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

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

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

        Вам бы ещё правила с не/ни подучить…
        • 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(в смысле гем для генерации графических изображений математических выражений)?
  • НЛО прилетело и опубликовало эту надпись здесь

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