Luhn Formu的实现

2024-06-01 10:37:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在Python中实现Luhn Formula,下面是我的代码:

import sys


def luhn_check(number):
    if number.isdigit():
        last_digit = int(str(number)[-1])
        reverse_sequence = list(int(d) for d in str(int(number[-2::-1])))

        for i in range(0, len(reverse_sequence), 2):
            reverse_sequence[i] *= 2

        for i in range(len(reverse_sequence)):
            if reverse_sequence[i] > 9:
                reverse_sequence[i] -= 9

        sum_of_digits = 0
        for i in range(len(reverse_sequence)):
            sum_of_digits += reverse_sequence[i]

        result = divmod(sum_of_digits, 10)

        if result == last_digit:
            print("[VALID] %s" % number)
        else:
            print("[INVALID] %s" % number)
        quit()

    print("[ERROR] \" %s \" is not a valid sequence." % number)
    quit()


def main():
    if len(sys.argv) < 2:
        print("Usage: python TLF.py <sequence>")
        quit()

    luhn_check(sys.argv[1])

if __name__ == '__main__':
    main()

但它不能正常工作:

[INVALID] 4532015112830366
[INVALID] 6011514433546201
[INVALID] 6771549495586802

等等。。。

但代码的逻辑在我看来是可以的。我遵循此工作流:

卢恩公式:

  1. 从数字中删除最后一个数字。最后一个数字是我们要核对的 将数字倒转

  2. 将奇数位置(1、3、5等)中的数字乘以2,再减去9,则所有大于9的结果均为9

  3. 将所有数字相加

  4. 校验位(卡的最后一个号码)是您需要添加的金额,才能得到10的倍数(模10)


Tags: ofinnumberforlenifsysrange
3条回答

我认为算法不正确。

第二步您需要对产品的数字求和,而不是减去9。引用:Wikipedia

在Wikipedia中有一个例子:

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)

结果:

>>>Correct:True
>>>Correct:True
>>>Correct:True

代码中有一些错误:

result = divmod(sum_of_digits, 10)

返回一个元组,只需要模,即

result = sum_of_digits % 10

第二,为了检查有效性,不省略最后一个数字(即校验和),而是将其包含在计算中。使用

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

并检查结果是否为零:

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

或者如果您坚持保持这种不需要的复杂性,请检查最后一个数字是否为校验和模10的逆数:keep

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

但是使用

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

对于更简单和更短的代码,我可以给您一个对my older answer的引用。

看这个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 )

相关问题 更多 >