import Data.Char
card = "4024 6072 3695 0748"
cardDigits = map digitToInt . filter (not . isSpace)
doubleDigitSum d = 2 * d - if d<5 then 0 else 9
doubleEveryOther = reverse . zipWith ($) (cycle [doubleDigitSum,id]) . reverse
main = let
cd = cardDigits $ card
sd = sum . doubleEveryOther . init $ cd
checkDigit = (- (sd + last cd)) `mod` 10
in print checkDigit
bediger4000•17m ago
I'm not conversant in Haskell, but this probably won't work on American Express card numbers - they have 15 digits, the final digit is still the Luhn checksum.
I did credit card processing 20 years ago - AmEx was very often the fly in the ointment.
tromp•11m ago
The above code works irrespective of the number of digits. It just follows the spec given in the article, specifically:
1. Write out all but the last digit of the card number.
2. Write out all but the last digit of the card number.
3. Starting from the right, double every other number.
tromp•1h ago
bediger4000•17m ago
I did credit card processing 20 years ago - AmEx was very often the fly in the ointment.
tromp•11m ago