こちらの記事 を参考にして、Haskell でマイナンバーのチェックデジットを計算するコードを書いてみました。
チェックデジットの具体的な計算方法は こちらの記事 を参照してください。
コード
myNumber.hs
import Data.Char
validateMyNumber :: String -> Bool
validateMyNumber cs = if (length cs == 12) && (all isDigit cs)
then last cs == calcCheckDigit (init cs)
else error "inappropriate data"
calcCheckDigit :: String -> Char
calcCheckDigit cs = if x <= 1 then '0' else intToDigit (11 - x)
where
ps = map digitToInt cs
qs = map (subtract 5) [11, 10 .. 7] ++ map (+ 1) [6, 5 .. 1]
x = rem (sum $ zipWith (*) ps qs) 11
コードの解説
validateMyNumber
関数
マイナンバーの先頭の数字が "0" であった場合にも対応できるように、データを文字列で与えるようにしました。
データが 12 桁でなかった場合やデータに数字以外の文字が入っていた場合、エラーを返します。
calcCheckDigit
関数
ps = map digitToInt cs
与えられた文字列 cs
を 整数のリスト ps
に変換します。n 桁目の数字を Pn とすると ps = [P11, P10 .. P1]
となっています。
qs = map (subtract 5) [11, 10 .. 7] ++ map (+ 1) [6, 5 .. 1]
ps
に合わせて qs = [Q11, Q10 .. Q1]
となるように、整数のリスト qs
を作ります。
x = rem (sum $ zipWith (*) ps qs) 11
$ \left( \sum_{n=1}^{11}P_n \times Q_n \right) % 11 $ を計算します。
追記
qs
はマイナンバーの数字に関係なく常に同じなので、定数として関数の外側で定義した方がいいかもしれません。