Luhn Algorithm to check for validity of bank card numbers
The Luhn algorithm is used to check bank card numbers for simple errors such as mistyping a digit, and proceeds as follows:
- consider each digit as a separate number;
- moving left, double every other number from the second last;
- subtract 9 from each number that is now greater than 9;
- add all the resulting numbers together;
- if the total is divisible by 10, the card is valid.
Let's see how we can implement the algorithm in Haskell for a simple case of four-digit number. We divide the problem into two steps:
- A function
luhnDouble
that doubles a digit and subtracts 9 if the result is greater than 9, and - A function
luhn
that decides if a four-digit number is valid based on the above algorithm.
luhnDouble :: Int -> Int
luhnDouble n | n*2 > 9 = n*2 - 9
| otherwise = n*2
luhn :: Int -> Int -> Int -> Int -> Bool
luhn a b c d =
(luhnDouble a + b + luhnDouble c + d) `mod` 10 == 0
Note how the guard equation makes even a single if-then-else conditional more readable.
*Main> luhn 2 2 7 9
True
*Main> luhn 7 8 9 3
False
It would be nice to extend it to a function that accetps card numbers of any length.