Welcome, guest | Sign In | My Account | Store | Cart

Test validity of any credit card number using the LUHN method (mod 10). Starting at the last digit and moving backwards, you add up every other digit. Then, you double the left-out digits, and add the digits of these results to the original sum. If this satisfies sum mod 10 == 0 then the card is valid.

This is also explained at http://www.beachnet.com/~hstiles/cardtype.html

Python, 18 lines
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18``` ```import re def validate(number): 'Validates any credit card number using LUHN method' number = str(number) re.sub(r' ', '', number) count = 0 for i in range(len(number)): val = int(number[-(i+1)]) if i % 2 == 0: count += val else: count += int(str(2 * val)[0]) if val > 5: count += int(str(2 * val)[1]) if count % 10 == 0: return True else: return False ```

Rogier Steehouder 10 years, 11 months ago

Some constructive criticism:

re.sub() returns the altered string. You have to assign it to a variable.

Do not use regular expressions where str.replace() works fine:

``````number = number.replace(' ', '')
``````

Don't do math with strings. Floor division (//) and remainder (%) work well for this.

Have a look at list comprehensions.

My version:

``````def validate(number):
# each digit in number as an int in reverse order
numlist = [int(c) for c in reversed(str(number)) if c.isdigit()]
count = 0
# automatic numbering
for i, val in enumerate(numlist):
if i % 2 == 0:
count += val
else:
# first digit of the double value
count += (2 * val) // 10
# last digit of the double value
count += (2 * val) % 10
# no need for an if statement
return (count % 10 == 0)
``````

or even:

``````def validate(number):
numlist = [int(x) for x in reversed(str(number)) if x.isdigit()]
# digits that count once
count = sum(x for i, x in enumerate(numlist) if i % 2 == 0)
# digits that count double (add digits of double value)
count += sum(sum(divmod(2 * x, 10)) for i, x in enumerate(numlist) if i % 2 != 0)
return (count % 10 == 0)
``````
Shawn Zhang 10 years, 6 months ago

I've practise a more short version with credit card number in string :

``````def validation_creditcard(string_number):
list_doubled = [ int(x)*2 for n,x in enumerate(string_number[::-1]) if n%2 != 0 ]
list_A = reduce(lambda x,y: x+y,map(lambda x:list(str(x)), list_doubled))
list_B = [x for n,x in enumerate( string_number[::-1] ) if n%2 == 0 ]
return reduce(lambda x,y:int(x)+int(y), list_A+list_B) % 10 == 0
``````
 Created by Stijn de Graaf on Thu, 11 Aug 2011 (MIT)