checksum-0.0: src/Math/Checksum/CitizenCard/Germany.hs
{- |
Personalausweisnummer
<https://de.wikipedia.org/wiki/Ausweisnummer>
-}
module Math.Checksum.CitizenCard.Germany (construct) where
import qualified Data.List.HT as ListHT
import Math.Checksum.Utility (decomposePositional)
digits :: Int -> Int -> [Int]
digits n x = reverse $ ListHT.padRight 0 n $ decomposePositional 10 x
check3 :: [Int] -> Int
check3 = flip mod 10 . sum . zipWith (*) (cycle [7,3,1])
addCheck3 :: [Int] -> [Int]
addCheck3 xs = xs ++ [check3 xs]
string :: [Int] -> String
string = concatMap show
{- |
> construct city no birthDate expiration
> construct 1234 56789 980706 180706 == "1234567897D<<9807062<1807066<<<<<<<8"
-}
construct :: Int -> Int -> Int -> Int -> String
construct city no birth expire =
let dno = addCheck3 $ digits 4 city ++ digits 5 no
dbirth = addCheck3 $ digits 6 birth
dexpire = addCheck3 $ digits 6 expire
in string dno ++ "D<<" ++
string dbirth ++ "<" ++
string dexpire ++ replicate 7 '<' ++
show (check3 $ dno ++ dbirth ++ dexpire)