CAPTCHA Perl. Генерация при помощи ImageMagick

Небольшая функция генерации капчи для 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.

Написано на правах памятки для себя, но вдруг кому пригодится 🙂



Category Рубрики: Интернет, Кодинг | Tag Метки: , , | Comments 13 комментариев »

13 комментариев

  1. mike says:

    Что-то не работает!
    Рисунок — просто белый прямоугольник,без текста, а потом
    вываливается на
    print $query->em(«»),
    $query->textfield(
    -name => ‘cap_value’,
    -size => 2,
    -maxlength => 2,
    );

    с сообщением
    Can’t call method «em» on an undefined value at /home/…….

    • dimio says:

      В примере указано так:

      print $query->em(««),

      ,а вы передаёте пустую строку.
      Модуль CGI подключен кстати?

      Что касается рисунка — во-первых — шрифт указан правильно? Во-вторых — можно покрутить параметры генерации. У меня получалась нормальная картинка с капчей при указанных в примере параметрах.

    • dimio says:

      Понятно, это движок режет код…

  2. mike says:

    Сделал так:
    $query = new CGI;
    print $query->em(«»),
    $query->textfield(
    -name => ‘cap_value’,
    -size => 10,
    -maxlength => 5,
    );
    все заработало, но картинка пустая 🙁

  3. bash says:

    вот сделал капчу… все работает.
    а как правильно проверять ее и ввод юзера ?

    • dimio says:

      Я бы вычислял хэш сгенерированного слова для капчи и хэш пользовательского ввода, а затем сравнивал их. Модуль Digest::MD5 в помощь.

  4. bash says:

    ну хэш пользовательского ввода вычислить без проблем… а вот хэш капчи как ?? он же уже забыт, т.к. скрипт отработался на выводе капчи ). да и вобще это разные скрипты могут быть — один выводит капчу, а другой принимает ввод… вот и заморочка у меня тут (

    • dimio says:

      Хэш капчи класть в файл или иную БД (в файл логичней и проще, но если уже есть БД для движка — почему бы не создать там таблицу), отработавшие (и при желании — протухшие) хэши капч удалять. Для удобства можно капчам идентификаторы присваивать некие.

  5. Araik says:

    Как связаться с Автором?

  6. rni says:

    Скачал исходный код, у меня создался файл нулевого размера cap_test.png.
    Ubuntu 14+perl 5.18 +ImageMagick 6.9.0
    Понимаю, что проблема у меня. Прошу у гуру помочь разобраться

Добавить комментарий