Friday, October 07, 2011

Luhn algorithm in elisp

I was looking for the checksum validation of credit card numbers and came across the Luhn Algorithm. I had emacs open and on a whim decided I'll try and implement it using elisp. I'm no lisp programmer but, have in the past managed to write some basic elisp in .emacs so, I guessed it would take me about .5hr at most.

I guessed wrong. It took me a lot longer to wrap my head around even some of the simple elisp constructs like let and lambda took quite a while and it took a lot longer than I anticipated. Here, I present to you the fruit of my labors :)
(defun luhn-sum (list n)
  (if (null list)
      0
    (+ (let ((x (car list)))
      (if (= 1 (mod n 2))
   (let ((y (* 2 x)))
     (if (> y 9) 
         (+ 1 (mod y 10)) 
       y))
        x))
       (luhn-sum (cdr list) (+ 1 n)))
    )
)

(defun luhn-check (card-no)
  (eq 0 (mod (luhn-sum (mapcar (lambda (x) (string-to-number x 10)) (cdr (reverse (cdr (split-string card-no ""))))) 0) 10))
)

(luhn-check "49927398716")

No comments: