Небольшая функция генерации капчи для perl при помощи вызова imagemagick через библиотеку Image::Magick.
Может пригодиться в том случае, когда хостер не позволяет устанавливать свои модули для perl (например GD::SecurityImage или Auchten::Captcha). Модуль для работы с ImageMagick не стоит по умолчанию разве что у самого нерадивого хостера.
Функцию можно использовать как библиотечный вызов, при вызове передавать имя файла и строку для генерации капчи.
#!/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;
# Вызов капчи из скрипта
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 = 'https://dimio.org'.$cap_url;
print $query->em(""),
$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
Понимаю, что проблема у меня. Прошу у гуру помочь разобраться