Как стать автором
Обновить

Капча с помошью MagickWand

Время на прочтение3 мин
Количество просмотров727
Всем привет.
Как я уже рассказывал, по стечению обстоятельств мне пришлось познакомится с интерфейсом к ImageMagick — MagickWand for PHP. Как оказалось, библиотека довольно мощная и интересная.
Ну и в качестве эксперимента, а так же на будущее, мной была сделана функция генерации капчи с использованием этой библиотеки. Преимущество ее в том, что нам не приходится писать картинку на диск а потому удалять ее. Все происходит, так сказать, «на лету».
Вот, что у меня получилось


Сначала форма и проверка:
<?php 
if ($_POST['submitbutton'] === 'ok') { // проверяем, не была ли нажата кнопка. Если была, то проверяем пользовательский ввод
if (md5($_POST['check']) != $_POST['str']) { // $_POST['check'] - это то, что юзер ввел. $_POST['str'] - хэш сгенерированной секретной строчки
echo 'FALSE'; // неправильно
}
else {
echo 'TRUE'; // правильно
}
}
function get_random_string($leight) // Функция генерирует строку символов
{
$ret="";
for ($i=0; $i<$leight; $i++)
{
if ( mt_rand(1,2) == 1 )
$char_code=mt_rand(48,57);
else
$char_code=mt_rand(97,122);
$ret.=chr($char_code);
}
return $ret;
}
session_start(); // сессию запустить необходимо, потому что в сессионных данных мы передаем значение секретной строчки генератору картинки
$rand_string = get_random_string(5); // генерируем строчку в 5 символов
$_SESSION['capt'] = $rand_string; // присваиваем переменной эту строчку
$capt = '<img src="capcha.php" />'; // это вызов скрипта, который генерит картинку

$str = md5($rand_string); // хэш строчки - для передачи через форму
echo $capt; // Показали картинку
?>
<!-- ФОРМА -->
<form action="test.php" method="post">
<input type="text" name="check" />
<input type="hidden" name="str" value="<?php echo $str; ?>" />
<button name="submitbutton" type="submit" value="ok">Проверить</button>


Теперь непосредственно генератор картинки
<?php
session_start(); //стартовали сессию
$secret = $_SESSION['capt']; //забрали переменную, в ней - строчка на капчу
$color = '#d67f25'; // цвет выбран от дуба
$background = NewMagickWand(); // новый Magicwand объект - будущая картинка
MagickNewImage($background,200,75,$color); // задали будущей картинке размеры и цвет
MagickSetImageFormat($background, 'png'); // формат - png
MagickAddNoiseImage($background,MW_ImpulseNoise); // добавили шума

$drawing=NewDrawingWand(); // новый объект - будущая надпись
DrawSetFont($drawing,"ACADEROM.TTF"); // взяли шрифт
DrawSetFontSize($drawing,48); // задали размер
DrawSetGravity($drawing,MW_SouthWestGravity); // гравитация. Координаты будут считаться от нижнего левого угла

for ($i = 1; $i <= 5; $i++) { цикл от 1 до количества букв в сгенерированной строке. В данном случае - 5

$r_st = substr($secret,($i-1),1); // берем символ
$angle_mod = rand(0,45); // случайный угол
$angle_polar = rand(0,1); // случайное число, определяет, будет угол положительным или отрицательным
if ($angle_polar == 1) { // в этом случае угол положительный
$angle = $angle_mod;
}
else { // а в этом - отрицательный
$angle = '-'.$angle_mod;
}
$letter_color_1 = dechex(rand(0,255)); // генерим число для цвета. Три раза
$letter_color_2 = dechex(rand(0,255));
$letter_color_3 = dechex(rand(0,255));
$letter_color = '#'.$letter_color_1.$letter_color_2.$letter_color_3; // таким цветом у нас будет буква

$fontcolor_light=NewPixelWand(); // объект MagickWand для цвета шрифта.
PixelSetColor($fontcolor_light,"#000000"); // сформировали цвет для нижнего слоя букв - черный
DrawSetFillColor($drawing,$fontcolor_light); // задали объекту цвет
MagickAnnotateImage($background,$drawing,($i*30),0,$angle,$r_st); // написали букву черным цветом

$fontcolor_light=NewPixelWand(); // то же, только для верхнего слоя
PixelSetColor($fontcolor_light,"$letter_color"); // теперь берем наш случайный цвет
DrawSetFillColor($drawing,$fontcolor_light); // задаем его объекту
MagickAnnotateImage($background,$drawing,($i*30),1,$angle,$r_st); // и пишем буковку этим цветом
}
header('Content-type: image/jpeg');
MagickEchoImageBlob($background); // нарисовали картинку
?>

Таким образом, во время выполнения первого скрипта мы генерируем случайную строчку символов, которую в глобальном массиве $_SESSION отдаем генератору картинки, который уже разбирает эту строку и рисует буквы/цифры со случайным углом наклона и случайного цвета.

А теперь у меня вопрос к специалистам!
Насколько устойчивой является данная капча? Можно ли ее как-то легко обойти? Я-то думаю, что нельзя, но, как обычно, сомневаюсь…
Теги:
Хабы:
-3
Комментарии27

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн