In today’s Programming Praxis exercise our goal is to write to functions related to the Luhn credit card number verification algorithm: one to check if a number is valid and one to make a valid number from a given number by adding one digit. Let’s get started, shall we?

Some imports:

import Data.Char
import Data.List.HT
import Test.QuickCheck

For both functions we need to calculate the Luhn sum of a number, so let’s start with that. This one simply follows the description given in the exercise text. You could probably speed it up a bit by replacing the multiplication with a lookup table.

luhnSum :: Integral a => a -> a
luhnSum n = digitSum a + digitSum (show . (* 2) . digitToInt =<< b)
where [a,b] = sliceHorizontal 2 . reverse $ show n
digitSum = sum . map (fromIntegral . digitToInt)

Checking if a number is valid is trivial: just see if the Luhn sum is zero.

isValid :: Integral a => a -> Bool
isValid n = mod (luhnSum n) 10 == 0

Making a valid number means adding the complement of the Luhn sum of 10 times the number (to account for the digit that will be added on the end) to the end of the number. The outer modulo is to account for the case where the Luhn sum is zero.

makeValid :: Integral a => a -> a
makeValid n = 10*n + mod (10 - mod (luhnSum $ 10*n) 10) 10

Some testing to see if everthing is working properly:

prop_luhn :: Integer -> Property
prop_luhn n = n >= 0 ==> isValid (makeValid n)
main :: IO ()
main = do print $ isValid 0
print $ isValid 34
print $ isValid 117
print $ isValid 49927398716
print . not $ isValid 49927398715
print $ makeValid 4992739871 == 49927398716
quickCheck prop_luhn

Yup. Have fun committing credit card fraud 🙂

### Like this:

Like Loading...

*Related*

Tags: bonsai, card, code, credit, Haskell, kata, luhn, praxis, programming

This entry was posted on April 8, 2011 at 11:54 am and is filed under Programming Praxis. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

## Leave a Reply