まだ手元には届いてないけど、マイナンバー制度始まりましたね。とある業務で、マイナンバーのチェックデジットを計算するロジックを書いたので記録。
業務で必要だったのはJavaScript。で、なんとなく書きたくなって書いたのがGroovy。間違えてたら、大変なのでご指摘いただけるとうれしいです。
ちなみに、個人用のマイナンバーは12桁の1桁目がチェックデジット。法人用マイナンバーは13桁の13桁目がチェックデジット。
個人用マイナンバーのチェックデジットは、法律で以下のように定義されている。
第五条 令第八条の総務省令で定める算式は、次に掲げる算式とする。
算式
11―(n=1(シグマ)11(Pn×Qn))を11で除した余り)
ただし、(n=1(シグマ)11(Pn×Qn))を11で除した余り≦1の場合は、0とする。
算式の符号
Pn 個人番号を構成する検査用数字以外の十一桁の番号の最下位の桁を1桁目としたときのn桁目の数字
Qn 1≦n≦6のとき n+1 7≦n≦11のとき n―5
JavaScript版
これをJavaScriptで書くと、こんな感じ。
function calcCheckdigit(myno) {
var divisor = 11;
var sigma = 11;
var sum = 0;
var pn = 0, qn = 0;
for (var n = 1; n <= sigma; n++) {
pn = parseInt(myno.substr(sigma - n, 1));
qn = (n >= 1 && n <= 6) ? n + 1 : n - 5;
sum += pn * qn;
}
return (sum % sigma <= 1) ? 0 : divisor - (sum % divisor);
}
マイナンバー 123456789018 のチェックデジットが正しいかは、こんな感じで求める。
var myno = "123456789018";
var checkDigit = calcCheckdigit(myno);
(checkDigit.toString() === (myno.substring(myno.length - 1, myno.length)));
Groovy版
続いて、あまり需要のなさそうなGroovyで書いた場合。
def myno = "123456789018"
def divisor = 11
def sigma = 11
def sum = 0
def pn = 0, qn = 0
(1..sigma).each { n ->
pn = myno[sigma - n] as int
qn = (n >= 1 && n <= 6) ? n + 1 : n - 5
sum += pn * qn
}
def checkDigit = (sum % sigma <= 1) ? 0 : divisor - (sum % divisor)
println(checkDigit)
assert(checkDigit as String == myno[myno.length() - 1])
法人番号をJavaScriptで
法人番号のチェックデジットは、JavaScriptでしか書いてない。
インターフェースが個人番号と違うのは、自覚してます…。
function isCorporateCheckdigit(myno) {
var divisor = 9;
var sigma = 12;
var sum = 0;
var pn = 0, qn = 0;
for (var n = 1; n <= sigma; n++) {
pn = parseInt(myno.substr(myno.length - n, 1));
qn = (n % 2 == 1) ? 1 : 2;
sum += pn * qn;
}
var checkDigit = divisor - (sum % divisor);
console.log(checkDigit);
return (checkDigit.toString() === (myno.substring(0, 1)));
}