2

I am trying to implement the Luhn's algorithm to check for credit card number validity. To do this every second digit needs to be multiplied by 2 and if the result is >9 it then is replaced by the sum of the digits.

def luhn_check(creditcardnr):
"""
check if credit card number is valid using the Luhn's algorithm
"""

som = 0
for i, digit in enumerate([int(x) for x in str(creditcardnr)]):
    if i in range(1, len(str(creditcardnr))-1,2):
        digit *= 2
        if digit > 9:
            digit -= digitsum(digit)
    som += digit
    print('digit :',digit,'    sum :',som)

return som % 10 == 0

When I run this code I get as result

digit : 5    sum : 5
digit : 2    sum : 7
digit : 2    sum : 9
digit : 9    sum : 18
digit : 7    sum : 25
digit : 2    sum : 27
digit : 0    sum : 27
digit : 9    sum : 36
digit : 3    sum : 39
digit : 9    sum : 48
digit : 6    sum : 54
False

the second sum should be 9 not 7

digitsum() is a function that replaces an integer by the sum of it's digits

  • 2
    This page may help you, https://en.wikipedia.org/wiki/Luhn_algorithm near the bottom is a Python example – Xantium Jul 29 '18 at 09:57
  • 1
    You're printing the modified value of `digit`, not the actual digit (and also `digit -= digitsum(digit)` is wrong, and `if i in range(1, len(str(creditcardnr))-1,2)` is a verbose and buggy way to check whether `i` is odd). – user2357112 Jul 29 '18 at 10:00

1 Answers1

0

Your code does not work against 52297209396 - assuming:

def digitsum(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

But neither does the Wikipedia version - per Simon's comment:

def check_luhn(purported_cc):
    sum_ = 0
    parity = len(purported_cc) % 2
    for i, digit in enumerate([int(x) for x in purported_cc]):
        if i % 2 == parity:
            digit *= 2
            if digit > 9:
                digit -= 9
        sum_ += digit
    return sum_ % 10 == 0

print(luhn_check(52297209396))  # False

However, with digitsum(n) defined above, I cannot reproduce your error:

the second sum should be 9 not 7

('digit :', 5, '    sum :', 5)
('digit :', 4, '    sum :', 9)
('digit :', 2, '    sum :', 11)
('digit :', 9, '    sum :', 20)
('digit :', 7, '    sum :', 27)
('digit :', 4, '    sum :', 31)

So I'm assuming 52297209396 is invalid.

The number 79927398713 (an example of a working number, via Wikipedia) does work against the Wikipedia statement of the algorithm (check_luhn() returns True, luhn_check() returns False) - so you could try using that instead.

alex
  • 6,818
  • 9
  • 52
  • 103