個人番号の送付のことがメディアなどで話題になっています。

この番号は住所や出席番号のように、一つずらしたものが次の別の番号になってしまうようなことはないような仕組みがあるだろうなあと思っていましたが、チャットで話題にしたところ、その算出方法(総務省令第八十五号)が公開されていることを知りました。

Ruby - マイナンバーのチェックデジットを計算する - QiitaでRubyのスクリプトが記されていたので、これを写して走らせてみようと思いましたが、Rubyは知らない、実行時に出たエラーは手に負えないとヘタレな状態なのでこれを使うのは諦めました。

しかし、先日、個人番号の通知が届いたこともあり、同様のことを行うPerlのスクリプトを書くことにしました。
次がそのPerlのスクリプトです。
 
#!/bin/perl -w
# 総務省令第八十五号
# http://www.soumu.go.jp/main_content/000327387.pdf
# に基づく個人番号の正当性の確認

die("個人番号を引数に指定してください\n") if ($#ARGV < 0);

my $number = $ARGV[0];		# 個人番号を引数で指定
die("12桁の数値を入力してください\n") unless (length($number) == 12);

my $check_digit = $number % 10;	# 検査用数字(一桁目の数値)
$number = reverse int($number /= 10); # 一桁目を削った数値を反転

my $n = 1;			# 桁位置
my $sum = 0;			# Σの計算
foreach my $p (split //, $number) {
    my $q = $n <= 6 ? $n + 1: $n - 5;
    $sum += $p * $q;
    $n++;
}

my $remainder = $sum % 11;

my $formula_solution = 11 - $remainder; # 算式の解
$formula_solution = 0 if ($remainder <= 1);

if ($check_digit == $formula_solution) {
    print "正当な値です\n";
}
else {
    print "不正な値です\n";
}
これをvalidate_persnum.plという名前で保存していますが、
validate_persnum.pl 123456789012

のように引数に12桁の番号を指定すれば結果を表示します。上記の数値の場合には次のようになります。

$validate_persnum.pl 123456789012
不正な値です

先ほどのRubyのスクリプトで試されていた値を同様に試したところ同じ結果となったので、計算は合っていると思います。

試しに自分の個人番号を入力してみましたら、もちろんですが、正常な値と判別されました。