Perlで偽造クレジットカードを見分ける

元の数)4417 1234 5678 9113


この右の2桁目からひとつ置きに2倍に掛けてみると...


8 2 2 6 10 14 18 2


それを、元の数の右1桁目からひとつ置きに拾った数...


4 7 2 4 6 8 1 3


に足します。2桁の数は十の位と1の位を足して1桁にしましょう。


式)8+4+2+7+2+2+6+4+1+0+6+1+4+8+1+8+1+2+3=70


この最後に出た和が10で割れる数なら、そのクレジットカードは有効です。

知ってる? クレジットカード番号の意味と暗算認証術 : ギズモード・ジャパン

こんな記事を見かけたので,なんとなくPerlでやってみました.

#!/usr/bin/perl

use strict;
use warnings;

my $crd = '4417 1234 5678 9113';

my @num = ();
push @num, $1 while ( $crd =~ /(\d)/g );

die "$crd is bad." unless (@num == 16);

my $sum = 0;
for ( my $i = 0; $i < @num; $i++ ) {
    if ( $i % 2 ) {
        $sum += $num[$i];
    }
    else {
        my $tmp = $num[$i] * 2;
        $tmp = $1 + $2 if ( $tmp =~ /^(\d)(\d)$/ );
        $sum += $tmp;
    }
}

if ( $sum % 10 ) {
    print "$crd is bad.\n"
}
else {
    print "$crd is good!\n"
}

上記のスクリプトをコピペして credit_check.pl とか適当に名前つけて

$ chmod +x credit_check.pl
$ perl credit_check.pl
4417 1234 5678 9113 is good!

とやれば動きます.
スクリプト中の'4417 1234 5678 9113'の部分を任意の番号にして確認できます.
ちなみにスペースがなかったり,ハイフンでつないだりしても大丈夫です.


まぁこの程度なら暗算でいいですね.
うーん,もっと簡潔に書きたいなぁ.