
В этом топике я хочу вам рассказать о создании т.н. "матан-капчи" с использованием только 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);
Вместо заключения
Ещё несколько капч, сгенерированных этим скриптом:



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