Pull to refresh

Создание капчи только своими руками

Reading time 3 min
Views 6.6K
Вот на днях решил, что на страницу регистрации в срочном порядке нужно ставить капчу, боты на столько обнаглели, что без неё там хорошо себя чувствуют и зовут ещё больше ботов.
По запросу в поисковике «Скрипт капчи», выпадает столько готовых вариантов — что грех жаловаться, но все они мне не подходят — одни слишком страшные, другие через-чур мудренные.
Решено! Делаем капчу своими руками. Тема конечно избита, но процессом работы поделюсь.

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

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

image

Теперь нужны цифры. В предложенных мне вариантах скриптов — которые генерируют капчу, цифры рисовались текстом — менялся их цвет и размер.
Я же пошел другим путем и нарисовал 30 разных цифр — 3-мя различными шрифтами и закрасил их градиентом в цвета сайта.

image

Сохранив каждую цифру в отдельный файл и установив им размер height:22px; начинаю кодить:

Капча будет состоять из 6-ти цифр поэтому. Цифры присваиваются рандомно.

$pic1 = rand(1, 30);
$pic2 = rand(1, 30);
$pic3 = rand(1, 30);
$pic4 = rand(1, 30);
$pic5 = rand(1, 30);
$pic6 = rand(1, 30);


Для каждой переменной берется рандомно цифра от 1 до 30, максимальный порог — это количество файлов с цифрами (каждый файл подписан от 0.png до 30.png). Т.к цифры сохраненны в правильном порядке, то узнать какая из них нарисована в файле можно определив последнюю цифру из названия файла:

$pic1_value = substr($pic1, strlen($pic1)-1, 1);
$pic2_value = substr($pic2, strlen($pic2)-1, 1);
$pic3_value = substr($pic3, strlen($pic3)-1, 1);
$pic4_value = substr($pic4, strlen($pic4)-1, 1);
$pic5_value = substr($pic5, strlen($pic5)-1, 1);
$pic6_value = substr($pic6, strlen($pic6)-1, 1);


Т.е цифра 2 может храниться в файле 2.png, 12.png, 22.png и т.д.

Обязательно запомним код капчи и запишем его в сессию.


session_start();
$_SESSION['captha'] = "{$pic1_value}{$pic2_value}{$pic3_value}{$pic4_value}{$pic5_value}{$pic6_value}";


Теперь когда нам известны цифры — нам нужно их нарисовать на картинке размером 112x38px;

$dest = imagecreatetruecolor(112,38); # Сюда мы и будем рисовать
$back = imagecreatefromjpeg("../../pic/captha/back.jpg"); # Задний фон


Открываем также нужные нам цифры:


$var1 = imagecreatefrompng("../../pic/captha/{$pic1}.png");
$var2 = imagecreatefrompng("../../pic/captha/{$pic2}.png");
$var3 = imagecreatefrompng("../../pic/captha/{$pic3}.png");
$var4 = imagecreatefrompng("../../pic/captha/{$pic4}.png");
$var5 = imagecreatefrompng("../../pic/captha/{$pic5}.png");
$var6 = imagecreatefrompng("../../pic/captha/{$pic6}.png");

Задний фон рандомно двигаем по горизонтали и вертикали таким образом чтобы фон не выходил за рамки капчи.

imagecopyresampled($dest, $back, 0, 0, rand(0, 224), rand(0, 106), 112, 38, 112, 38); 


Сами цифры мы тоже копируем в капчу — рандомно изменяя позицию по вертикали и горизонтали, а также размер цифры максимум на 4px.

imagecopyresampled ($dest, $var1, rand(0, 6), rand(2, 10), 0, 0, imagesx($var1) - rand(0, 4), imagesy($var1) - rand(0, 4), imagesx($var1), imagesy($var1)); 
imagecopyresampled ($dest, $var2, rand(18, 24), rand(2, 10), 0, 0, imagesx($var2) - rand(0, 4), imagesy($var2) - rand(0, 4), imagesx($var2), imagesy($var2)); 
imagecopyresampled ($dest, $var3, rand(36, 42), rand(2, 10), 0, 0, imagesx($var3) - rand(0, 4), imagesy($var3) - rand(0, 4), imagesx($var3), imagesy($var3)); 
imagecopyresampled ($dest, $var4, rand(54, 60), rand(2, 10), 0, 0, imagesx($var4) - rand(0, 4), imagesy($var4) - rand(0, 4), imagesx($var4), imagesy($var4)); 
imagecopyresampled ($dest, $var5, rand(72, 78), rand(2, 10), 0, 0, imagesx($var5) - rand(0, 4), imagesy($var5) - rand(0, 4), imagesx($var5), imagesy($var5)); 
imagecopyresampled ($dest, $var6, rand(90, 96), rand(2, 10), 0, 0, imagesx($var6) - rand(0, 4), imagesy($var6) - rand(0, 4), imagesx($var6), imagesy($var6)); 

В принципе всё готово осталось только установить в начале php файла нужный заголовок:

header('Content-type: image/jpeg');


И вывести нарисованную капчу в браузер:
imagejpeg($dest);


Ну и разумеется не забыть очистить буфер:

imagedestroy($back);
imagedestroy($dest);
imagedestroy($var1);
imagedestroy($var2);
imagedestroy($var3);
imagedestroy($var4);
imagedestroy($var5);
imagedestroy($var6);


Сохраняем, проверяем.

image

Ставим в нужное место на сайте.

image

Если введенный код
!= $_SESSION['captha']
— то выводим соответствующую ошибку.

image

По мере необходимости в папку с капчей можно будет скопировать дополнительные цифры а максимальный порог в строках:

$pic1 = rand(1, 30); — увеличить.

На этом наша самоджельная улучшенная и простая капча, готова. Спасибо за внимание и не судите строга. Если кому то понравится пример, пользуйтесь на здоровье.
Tags:
Hubs:
-20
Comments 19
Comments Comments 19

Articles