みなさんのところにはマイナンバーは届きましたか?
ということで ネタがないので 先日うちにもマイナンバーが届いたので、Ruby - マイナンバーのチェックデジットを計算する - Qiitaなどの記事をみてKotlinでも実装してみました。
マイナンバーのチェックディジットの定義などは他の方々が詳細に書いてらっしゃるのでそちらを参考にしてください。
MyNumberValidator
object MyNumberValidator {
fun validate(str: String): Boolean = str
.apply {
if (length != 12) { throw IllegalArgumentException() }
if (!all { it.isDigit() }) { throw IllegalArgumentException() }
}
.take(11)
.reversed()
.map {it - '0'}
.zip(1..11)
.map{
val n = it.second
val p = it.first
val q = if (n <= 6) { n + 1 } else { n - 5 }
p * q
}
.sum()
.let { 11 - it % 11 }
.let {
val checkDigit = str.last() - '0'
when (it) {
0, 1 -> 0 == checkDigit
else -> it == checkDigit
}
}
}
fun main(args: Array<String>){
check(!MyNumberValidator.validate("123456789010"))
check(!MyNumberValidator.validate("123456789011"))
check(!MyNumberValidator.validate("123456789012"))
check(!MyNumberValidator.validate("123456789013"))
check(!MyNumberValidator.validate("123456789014"))
check(!MyNumberValidator.validate("123456789015"))
check(!MyNumberValidator.validate("123456789016"))
check(!MyNumberValidator.validate("123456789017"))
check(MyNumberValidator.validate("123456789018"))
check(!MyNumberValidator.validate("123456789019"))
check(MyNumberValidator.validate("023456789013"))
}
KotlinたしくSingle expressionで書いてみました。
ポイントは長さのチェックやすべて数字かどうかのチェックはapply式の中で行ってチェックに引っかかったらExceptionを投げつつ、最後のlet式で末尾のcheck digitと比較を行ったBooleanで結果を戻しているとこでしょうか。
ソースはこちらに置いておきます