Небольшая функция генерации капчи для perl при помощи вызова imagemagick через библиотеку Image::Magick.
Может пригодиться в том случае, когда хостер не позволяет устанавливать свои модули для perl (например GD::SecurityImage или Auchten::Captcha). Модуль для работы с ImageMagick не стоит по умолчанию разве что у самого нерадивого хостера.
Функцию можно использовать как библиотечный вызов, при вызове передавать имя файла и строку для генерации капчи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #!/usr/bin/perl # Генератор капчи. Идея и параметры вызова Convert взяты с captcha.ru (http://captcha.ru/captchas/multiswirl/). # Реализация под библиотеку Image::Magick для perl - dimio (dimio.org). # 27.09.2009 use Image::Magick; sub CreateCapImage($$){ my($cap_string,$filename) = @_; my $font = 'times.ttf'; my $pointsize = 70; my $path = './'; my $image = new Image::Magick; # 1. Создаём поле 300x100 белого цвета. $image->Set(size => '300x100'); $image->ReadImage('xc:white'); # 2. Печатаем черным с антиалиасингом $image->Set( type => 'TrueColor', antialias => 'True', fill => 'black', # строку STRING шрифтом $font размером $pointsize font => $font, pointsize => $pointsize, ); $image->Draw( primitive => 'text', points => '20,70', # ориентация строки текста внутри картинки text => $cap_string, # что печатаем ); # 3. Подвинуть центр влево на 100 точек +случайная флуктуация $image->Extent( geometry => '400x120', # меняем размер картинки ); $image->Roll( x => 101+int(rand(4)), ); # 4. Первый swirl на случайный угол (от 37 до 51) $image->Swirl( degrees => int(rand(14))+37, ); # 5. Подвинуть центр вправо на 200 точек, тоже со случайной флуктуацией $image->Extent( geometry => '600x140', # меняем размер картинки ); $image->Roll( x => 3-int(rand(4)), ); # 6. Второй поворот (от 20 до 35) $image->Swirl( degrees => int(rand(15))+20,, ); # 7. Окончательная обработка и вывод $image->Crop('300x100+100+17'); $image->Resize('150x50'); $filename = $path . $filename; $filename .= '.png'; open(IMAGE,'>',$filename) or die $!; $image->Write(file=>\*IMAGE, filename=>$filename); close(IMAGE); return $filename; } 1; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Вызов капчи из скрипта my $num1 = int(rand(11))+int(rand(3)); my $num2 = int(rand(8))+int(rand(4)); my $sum = $num1+$num2; my $cap_string = $num1.'+'.$num2.'='; my $cap_digest = md5_hex($sum+rand(100)+rand(50)); my $cap_url = &CreateCapImage($cap_string,$cap_digest); $cap_url =~ s|/home/dimioorg/public_html/dimioorg||; $cap_url = 'http://dimio.org'.$cap_url; print $query->em("<img src="$cap_url">"), $query->textfield( -name => 'cap_value', -size => 2, -maxlength => 2, ); |
В результате на странице будет выведена картинка с символами вида «12+7=». Строка в принципе может быть какой угодно.
Кому лень копипастить — может скачать функцию captcha.pl и три ttf шрифта. А еще для генерации капчи можно использовать специальный модуль Authen::Captcha.
Написано на правах памятки для себя, но вдруг кому пригодится :)
Что-то не работает!
Рисунок — просто белый прямоугольник,без текста, а потом
вываливается на
print $query->em(«»),
$query->textfield(
-name => ‘cap_value’,
-size => 2,
-maxlength => 2,
);
с сообщением
Can’t call method «em» on an undefined value at /home/…….
В примере указано так:
,а вы передаёте пустую строку.
Модуль CGI подключен кстати?
Что касается рисунка — во-первых — шрифт указан правильно? Во-вторых — можно покрутить параметры генерации. У меня получалась нормальная картинка с капчей при указанных в примере параметрах.
Понятно, это движок режет код…
Сделал так:
$query = new CGI;
print $query->em(«»),
$query->textfield(
-name => ‘cap_value’,
-size => 10,
-maxlength => 5,
);
все заработало, но картинка пустая :(
img src=\»$cap_url\» border=\»2\»
Запустил для проверки на сервере у себя: исходный код —
.
Perl v5.8.8
ImageMagick 6.5.9-9 2010-02-25 Q16
Image::Magick (6.005009)
вот сделал капчу… все работает.
а как правильно проверять ее и ввод юзера ?
Я бы вычислял хэш сгенерированного слова для капчи и хэш пользовательского ввода, а затем сравнивал их. Модуль Digest::MD5 в помощь.
ну хэш пользовательского ввода вычислить без проблем… а вот хэш капчи как ?? он же уже забыт, т.к. скрипт отработался на выводе капчи ). да и вобще это разные скрипты могут быть — один выводит капчу, а другой принимает ввод… вот и заморочка у меня тут (
Хэш капчи класть в файл или иную БД (в файл логичней и проще, но если уже есть БД для движка — почему бы не создать там таблицу), отработавшие (и при желании — протухшие) хэши капч удалять. Для удобства можно капчам идентификаторы присваивать некие.
Как связаться с Автором?
С автором чего именно?
Скачал исходный код, у меня создался файл нулевого размера cap_test.png.
Ubuntu 14+perl 5.18 +ImageMagick 6.9.0
Понимаю, что проблема у меня. Прошу у гуру помочь разобраться