I was trying to implement the Luhn Formula in Python. Here is my code:
import sys
def luhn_check(number):
if number.isdigit():
last_digit = int(
The main problem with your logic is that you are applying some computations that are only for the odd digits to the even digits too.
I have some suggestions for you:
Considering what I have suggested, this is how I would solve this problem. Notice that I am using Python's type annotations. I will also highlight the steps of Luhn's algorithm with comments.
def compute_sum_of_remainig_digits(remaining_digits: List[int]) -> int:
# use a list comprehension to extract digits in even positions
even_positions = remaining_digits[-2::-2]
# use a list comprehension to extract digits in odd positions
odd_positions = remaining_digits[-1::-2]
# 2. Multiply the digits in odd positions (1, 3, 5, etc.) by 2
# and subtract 9 to all any result higher than 9
computed_odd = [2 * d - 9 if 2 * d > 9 else 2 * d for d in odd_positions]
# 3. Add all the numbers together
return sum(even_positions + computed_odd)
def compute_checksum(number: str) -> int:
# the following line convert a string of digits into list of digits using map
# this way you do not need to explicitly declare a for loop
digits = list(map(int, number))
# 1. Drop the last digit from the number...
last_digit = digits[-1]
total = compute_sum_of_remainig_digits(digits[:-1 ])
# 4. The check digit (the last number of the card) is
# the amount that you would need to add...
return (total + last_digit)
def check_valid_number(number: str) -> bool:
# 4. ...to get a multiple of 10 (Modulo 10)
return (compute_checksum(number) * 9) % 10 == 0
Now let's validate the previous code:
>>> valid_number = "4929355681587216"
>>> invalid_number = "5183814022326227"
>>> check_valid_number(valid_number)
True
>>> check_valid_number(invalid_number)
False
I hope this answer helps you or helps other people in trouble to understand how to compute a Luhn's checker.
I think the algorithm is not correct.
The second step you need to sum the digits of the products instead of substract 9. Reference: Wikipedia.
In the Wikipedia you have this example:
def luhn_checksum(card_number):
def digits_of(n):
return [int(d) for d in str(n)]
digits = digits_of(card_number)
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
checksum = 0
checksum += sum(odd_digits)
for d in even_digits:
checksum += sum(digits_of(d*2))
return checksum % 10
def is_luhn_valid(card_number):
return luhn_checksum(card_number) == 0
result = is_luhn_valid(4532015112830366)
print 'Correct:' + str(result)
result = is_luhn_valid(6011514433546201)
print 'Correct:' + str(result)
result = is_luhn_valid(6771549495586802)
print 'Correct:' + str(result)
Result:
>>>Correct:True
>>>Correct:True
>>>Correct:True