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 :: 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)