LoginSignup
1
1

More than 5 years have passed since last update.

マイナンバーのチェックデジットを Haskell で計算してみる

Posted at

こちらの記事 を参考にして、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 はマイナンバーの数字に関係なく常に同じなので、定数として関数の外側で定義した方がいいかもしれません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1