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

This is an industry standard algorithm I ported to python. It works on all major credit cards. You pass in the credit card number as a string and it returns 1 for a valid card or 0 for an invalid card

Python, 18 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def cardLuhnChecksumIsValid(card_number):
    """ checks to make sure that the card passes a luhn mod-10 checksum """

    sum = 0
    num_digits = len(card_number)
    oddeven = num_digits & 1

    for count in range(0, num_digits):
        digit = int(card_number[count])

        if not (( count & 1 ) ^ oddeven ):
            digit = digit * 2
        if digit > 9:
            digit = digit - 9

        sum = sum + digit

    return ( (sum % 10) == 0 )

This recipe was originally written for a now-defunct e-commerce application used within Zope.

It will save you time and money before trying to process a bad card with your credit card vendor, because you won't waste money trying to authorize a bad card with your credit card processing vendor.

The full suite of creditValidation methods are available here:

http://david.theresistance.net/files/creditValidation.py

8 comments

weeti 19 years, 9 months ago  # | flag

Checksum calculation.

""" easy checksum """
def checksum(a):
    return (10 - sum([int(y)*[7,3,1][x%3] for x, y in enumerate(str(a)[::-1])])%10)%10
sasa sasa 19 years, 6 months ago  # | flag

Another take...

# Return the "Luhn transform" of a digit.
luhnify = lambda digit: sum(divmod( digit*2, 10 ))

def luhn_checksum( digits ):
    """Return the Luhn checksum of a sequence of digits.
    """
    digits = map( int, digits )
    odds, evens = digits[-2::-2], digits[-1::-2]
    return sum( map(luhnify,odds) + evens ) % 10
Christopher Dunn 19 years, 2 months ago  # | flag

That checksum is wrong. It does not match the other 2 listed here, and it returns "7" for my credit card. What is it for?

Lloyd Girty 18 years, 2 months ago  # | flag

Integer only version. Here is a integer-only version that avoids string casts. You may need "from __future__ import division" to use the "//" floor operator.

def luhn(n):
    """luhnsum(int)->bool
    Mod 10 checksum by Hans Peter Luhn (1896–1964)
    """
    sum=0
    while n:
        r=n%100
        n//=100
        z=r%10
        r=r//10*2
        sum+=r//10+r%10+z
    return 0==sum%10
Lloyd Girty 18 years, 2 months ago  # | flag

generating many luhn numbers.

def nextLuhn(n):
    """nextLuhn(int) -> int
    Gets the smallest Luhn number greater than n.
    Uses a naive (exhaustive) algorithm that must try
    the Luhn checksum an average of 10 times.
    """
    n+=1
    while not luhn(n):
        n+=1
    return n

def biggerLuhn(n):
    """ biggerLuhn(int) -> int
    Gets a Luhn number greater than n.
    Uses a probability model that is very efficient if
    n passes the Luhn checksum.
    It may be possible to miss a Luhn number with this method.
    """
    for t in [8, 18, 7, 17, 6, 16]:
        if luhn(n+t):
            return n+t
    return nextLuhn(n)

def xluhn(seed,howmany):
    """xluhn(int,int) ->*int
    Yields Luhn numbers greater than the seed.
    Some numbers may be left out of the sequence.
    """
    while howmany:
        seed=biggerLuhn(seed)
        howmany-=1
        yield seed
James Coe 16 years, 8 months ago  # | flag

Incorrect LUHN checksum implementation. This LUHN implementation is actually incorrect. The card number digits must be traversed from end to beginning (reverse the direction the for loop counts) or some (but not all) perfectly valid card numbers will be rejected.

admin sekip 14 years, 10 months ago  # | flag
Bernard Opic 14 years, 7 months ago  # | flag

Here's another version, just written to see how Python compares to C in such a case.

def luhn( l ):

    s, i = 0, 16

    while i > 0:
        i -= 1
        v = ord( l[ 15 - i ] ) - 48 << i % 2
        if ( v > 9 ):
            s += v - 9
        else:
            s += v

    return s % 10 < 1

You can find details and execution timing results here.

As this is my very first coding experience with Python, comments and advices are welcome :-)

Created by David Shaw on Wed, 8 Jan 2003 (PSF)
Python recipes (4591)
David Shaw's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks