あわせて読みたい
言語 | リンク |
---|---|
Ruby | マイナンバーのチェックデジットを計算する |
C++ | C++でマイナンバーのチェックデジットを計算する |
Python | Python マイナンバー検証用モジュールを公開 |
PHP | マイナンバーのチェックデジットを計算する PHP版 |
C# | C#でマイナンバーのチェックデジットを計算する |
SQL | マイナンバーのチェックデジットを計算する(SQLで) |
PowerShell | WindowsPowerShell & C#マイナンバーのチェックデジットを計算する |
JavaScript, Groovy | JavaScriptとGroovyでマイナンバーのチェックデジットを計算する |
Haskell | Haskellでマイナンバーのチェックデジットを計算する |
Haskell | マイナンバー数字列の確認 |
Java | マイナンバーのチェックデジットを計算する(Java編) |
C, Go, Bash, Excel etc... | マイナンバーのチェックデジットの検算をざっくり1割くらい高速化する(計ってないので知らんけど) |
Go | マイナンバーのチェックデジットをGoで計算する |
Swift | マイナンバーのチェックデジットをSwiftで計算する |
Vim script | Vim からマイナンバーを検証出来るプラグイン書いた。 |
Gauche | Scheme(Gauche)でマイナンバーのチェックデジットを計算する |
OCaml | OCaml でマイナンバーのチェックデジットを計算する |
Rust | My Number validator for Rust |
説明
流行に乗ってマイナンバーのチェックデジットを計算してみます。
Ruby 版を真似て書いています。
Perl5
mynumber_validate.pl
#!/usr/bin env perl
use v5.18;
use List::Util 'sum';
use feature qw(say switch);
no warnings 'experimental';
&main;exit;
sub main{
say validate_my_number('123456789010'); #=> false
say validate_my_number('123456789011'); #=> false
say validate_my_number('123456789012'); #=> false
say validate_my_number('123456789013'); #=> false
say validate_my_number('123456789014'); #=> false
say validate_my_number('123456789015'); #=> false
say validate_my_number('123456789016'); #=> false
say validate_my_number('123456789017'); #=> false
say validate_my_number('123456789018'); #=> true
say validate_my_number('123456789019'); #=> false
say validate_my_number('023456789013'); #=> true (先頭が0の場合)
}
sub validate_my_number{
# 整数列化
my @digits = split'', $_[0];
# 12桁しか認めない
return 'false' unless @digits == 12;
# チェックデジットを分離します
my $check_digit = pop @digits;
# P(n) 定義
my $P = sub {
my @digits = @_;
return sub {
my $n = $_[0];
return $digits[ -$n ];
};
}->(@digits);
# Q(n) 定義
my $Q = sub {
my $n = $_[0];
return ($n<= 6) ? $n+1 : $n-5;
};
# 数列の和を11で割った余りを計算します
my $remainder = ( sum map{ $P->($_) * $Q->($_) } 1..11 ) % 11;
given( $remainder ){
when ([0,1]){
return $check_digit == 0 ? 'true' : 'false';
}
default{
return $check_digit == 11 - $remainder ? 'true' : 'false';
}
}
}
Perl6
perl6_mynumber_validate.pl
use v6;
sub MAIN (){
say validate_my_number('123456789010'); #=> false
say validate_my_number('123456789011'); #=> false
say validate_my_number('123456789012'); #=> false
say validate_my_number('123456789013'); #=> false
say validate_my_number('123456789014'); #=> false
say validate_my_number('123456789015'); #=> false
say validate_my_number('123456789016'); #=> false
say validate_my_number('123456789017'); #=> false
say validate_my_number('123456789018'); #=> true
say validate_my_number('123456789019'); #=> false
say validate_my_number('023456789013'); #=> true (先頭が0の場合)
}
sub validate_my_number( Str $mynumber ){
# 整数列化
my @digits = $mynumber.comb;
# 12桁しか認めない
return False unless @digits.elems == 12;
# チェックデジットを分離します
my $check_digit = @digits.pop;
# P(n) 定義
my $P = sub ( @digits ) {
return sub ( Int $n ) {
return @digits[ *-$n ];
};
}.(@digits);
# Q(n) 定義
my $Q = sub ( Int $n ) {
return ($n <= 6) ?? $n + 1 !! $n - 5;
};
# 数列の和を11で割った余りを計算します
my $remainder = ( [+] (1..11).map:{ $P.(+$_) * $Q.(+$_) } ) % 11;
given $remainder {
when 0|1 {
return $check_digit == 0;
}
default {
return $check_digit == (11 - $remainder);
}
}
}
おわりです。