北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

GD::SecurityImage in OS X

GD::SecurityImageOS Xに突っ込みました。

  1. sudo port install gd2
  2. sudo perl -MCPAN -e install GD
  3. sudo perl -MCPAN -e install GD::SecurityImage


見ての通り、MacPorts使ってます。


動作チェックをざっくりと。TTFフォントはSpotlightすれば速攻で探せますが、パスに空白が入ると駄目なので、コピーして名前変更して空白が入らないようにしましょう。後、相対パスでも駄目です。

#!/usr/bin/perl

use strict;
use GD::SecurityImage;
use CGI;
use Digest::MD5;


# キーとなる数字のダイジェストをとる
sub _digest($){
    # 塩を少々 (回数重ねたらバレそうだが)
    return Digest::MD5::md5_base64('mHhgLs' . shift);
}


# 画像表示のアクション
sub disp_image($){
    my $cgi = shift;
    my $image = GD::SecurityImage->new(
       width    => 300,
       height   => 120,
       lines    => 10,
       font     => "/あなたのTTFフォントへのパス/HOGEHOGE.ttf",
       ptsize => 32,
       scramble => 1
      );

    $image->random();
    $image->create(ttf => 'ec', '#990099', '#770077');
    $image->particle();

    my($image_data, $mime_type, $random_number) = $image->out;

    # クッキーに表示したイメージのダイジェストをつける
    my $cook = $cgi->cookie(
      -name => 'security', 
      -value => _digest($random_number));
    print $cgi->header(-type => "image/$mime_type", -cookie => $cook);
    print $image_data;
}


# 結果チェックのアクション
sub check($){
    my $cgi = shift;

    # クッキーのダイジェストと入力されたダイジェストの比較
    my $img_digest = $cgi->cookie('security');
    my $inp_digest = _digest($cgi->param('number'));
    my $ret = $img_digest eq $inp_digest ? 'OK' : 'NG';

    print $cgi->header(), <<_RESULT_;
<pre>
[RESULT]
CHECK: $ret
IMAGE: $img_digest
INPUT: $inp_digest
</pre>
_RESULT_
}


# フォーム表示のアクション
sub disp_form($){
    my $cgi = shift;
    print $cgi->header(), <<__FORM__;
<img src="index.cgi?act=disp_image" /><br />
<form action="index.cgi" method="POST">
<input type="hidden" name="act" value="check" />
<input name="number" /><br />
<input type="submit" />
</form>
__FORM__
}


# メインルーチン
my $cgi = new CGI();
my $act = $cgi->param('act');

# act=XXXX で処理を分ける
my $func = {
    check => ?&check, disp_image => ?&disp_image, disp_form => ?&disp_form,
}->{$act};

if($func){
    $func->($cgi);
}else{
    disp_form($cgi);
}