Python:信用卡验证码

时间:2014-01-11 21:25:10

标签: python validation

我的代码有问题。 它运行良好但在某些情况下(例如输入= 8913266562747895)它给出了错误的答案。 这是我的代码:

def ccv(s):
    k=list(s)
    if len(k)==19:
        for i in(0,1,2,3,5,6,7,8,10,11,12,13,15,16,17,18):
            if not k[i].isdigit():
                return False
        for i in(4,9,14):            
            if k[i]!=" " and k[i]!="-":
                return False
        l=[int(c) for c in s if c.isdigit()]
        if not 4<=l[0]and l[0]<=7:
            return False
        s=0
        for i in range(0,16, 2):
            l[i]=2*l[i]
            if l[i]/10!=0:
                l[i]= l[i]/10+(l[i]%10)       
        for i in range(16):
            s=s+l[i]
        return s%10==0
    elif len(k)==16:
        for i in range(16):
            if not k[i].isdigit():
                return False
        l=[int(c) for c in s if c.isdigit()]
        if not 4<=l[0]and l[0]<=7:
            return False
        else:          
            s=0
            for i in range(0,16, 2):
                    l[i]=2*l[i]
                    if l[i]/10!=0:
                        l[i]= l[i]/10+(l[i]%10)       
            for i in range(16):
                    s=s+l[i]
        return s%10==0
    else:
        return False
n=raw_input()
while n!="END" and n!="end":
    print ccv(n)
    n=raw_input()

你能告诉我问题出在哪里吗?

2 个答案:

答案 0 :(得分:7)

我认为你要找的是Luhn algorithm。它可以非常简洁地实现:

def luhn(input):
    digits = [int(c) for c in input if c.isdigit()]
    checksum = digits.pop()
    digits.reverse()
    doubled = [2*d for d in digits[0::2]]
    total = sum(d-9 if d > 9 else d for d in doubled) + sum(digits[1::2])
    return (total * 9) % 10 == checksum

Rosetta Code - Luhn Algorithm的版本更短,但可能性较差。

PayPal发布了一个好的list of fake credit card numbers来测试。

同时检查pycard,这是一个没有外部依赖关系的库。

答案 1 :(得分:0)

一个问题是这一行(以及else块中的重复行):

if not 4<=l[0]and l[0]<=7:
    return False

您需要使用括号以正确的方式进行解析:

if not (4<=l[0]and l[0]<=7):
    return False

更好的是:

if not 4 <= l[0] <= 7:
    return False