Implementation of Luhn Formula

情到浓时终转凉″ 提交于 2019-11-29 15:19:39

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
alko

There are some errors in your code:

result = divmod(sum_of_digits, 10)

returns a tuple, you need only modulo, that is use

result = sum_of_digits % 10

Second, to check for validity, you don't omit last digit (that is checksum), but include it in computations. Use

reverse_sequence = list(int(d) for d in str(int(number[::-1]))) 

And check for result being zero:

if not result:
    print("[VALID] %s" % number)

Or if you insist on keeping this not needed complexity, check for last digit to be inverse of checksum modulo 10: keep

reverse_sequence = list(int(d) for d in str(int(number[-2::-1])))

but use

if (result + last_digit) % 10 == 0:
    print("[VALID] %s" % number)

For a simplier and shorter code, I can give you a reference to my older answer.

see this Python recipe

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 )

The following might help some people to start with the Luhn algorithm in python.

num = list(input("Please enter the number to test (no space, no symbols, only \
numbers): "))

num = list(map(int, num))[::-1] #let's transform string into int and reverse it

for index in range(1,len(num),2):
    if num[index]<5:
        num[index] = num[index] *2
    else: #doubling number>=5 will give a 2 digit number
        num[index] = ((num[index]*2)//10) + ((num[index]*2)%10)

checksum=sum(num)

print("checksum= {}".format(checksum))

if checksum%10 !=0:
    print('the number is not valid')
else:
    print('the number is valid!')

I'd keep it simple and easy to read, something like this:

def luhn(value):
    digits = map(int, str(value))
    oddSum = sum(digits[-1::-2])
    evnSum = sum([sum(divmod(2 * d, 10)) for d in digits[-2::-2]])
    return (oddSum + evnSum) % 10 == 0

But there's tons of ways to do the same thing. Obviously, you'd have to do it differently to see the actual output, this just sums up the total to determine if the value is valid.

Best!

This is the most concise python formula for the Luhn test I have found:

def luhn(n):
    r = [int(ch) for ch in str(n)][::-1]
    return (sum(r[0::2]) + sum(sum(divmod(d*2,10)) for d in r[1::2])) % 10 == 0

The above function and other Luhn implementations (in different programming languages) are available in https://www.rosettacode.org/wiki/Luhn_test_of_credit_card_numbers .

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!