Implementation of Luhn Formula

后端 未结 8 2028
礼貌的吻别
礼貌的吻别 2020-12-19 15:38

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(         


        
相关标签:
8条回答
  • 2020-12-19 16:30

    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:

    1. Instead of receiving an int as input, receive a string so you can handle numbers with trailing zeros.
    2. Try to apply list comprehensions or use map when processing a list
    3. You could define some helper functions to improve your code redability.

    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.

    0 讨论(0)
  • 2020-12-19 16:33

    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
    
    0 讨论(0)
提交回复
热议问题