Python信用卡验证

时间:2016-11-19 01:06:29

标签: python function validation python-3.x luhn

我是初学者Python学习者,我正在研究Luhn算法来检查信用卡验证。我编写了大部分代码,但是我遇到了2个错误,我得到的第一个是在分配之前引用了num。我得到的第二个是'_io.TextIOWrapper'类型的对象没有len()。将非常感谢进一步的帮助/指导。

以下是Luhn算法(Mod10检查)的步骤

  1. 从右到左加倍每秒。如果这个“加倍”导致两位数字,则添加两位数 数字得到一位数。
  2. 现在添加步骤1中的所有单个数字。
  3. 在信用卡号码中从右到左添加奇数位置的所有数字。
  4. 总结步骤2& 3。
  5. 如果步骤4的结果可被10整除,则卡号有效;否则,它无效。
  6. 这是我的输出应该是什么

    Card Number         Valid / Invalid
    --------------------------------------
    3710293             Invalid
    5190990281925290    Invalid
    3716820019271998    Valid
    37168200192719989   Invalid
    8102966371298364    Invalid
    6823119834248189    Valid
    

    这是代码。

    def checkSecondDigits(num):
        length = len(num)
        sum =  0
        for i in range(length-2,-1,-2):
          number = eval(num[i])
          number = number * 2
          if number > 9:
              strNumber = str(number)
              number = eval(strNumber[0]) + eval(strNumber[1])
              sum += number
          return sum
    
    def odd_digits(num):
        length = len(num)
        sumOdd = 0
        for i in range(length-1,-1,-2):
            num += eval(num[i])
        return sumOdd
    
    def c_length(num):
        length = len(num)
        if num >= 13 and num <= 16:
        if num [0] == "4" or num [0] == "5" or num [0] == "6" or (num [0] == "3" and num [1] == "7"):
            return True
        else:
            return False
    
    
    def main():
        filename = input("What is the name of your input file? ")
        infile= open(filename,"r")
        cc = (infile.readline().strip())
        print(format("Card Number", "20s"), ("Valid / Invalid"))
        print("------------------------------------")
        while cc!= "EXIT":
            even = checkSecondDigits(num)
            odd = odd_digits(num)
            c_len = c_length(num)
            tot = even + odd
    
            if c_len == True and tot % 10 == 0:
                print(format(cc, "20s"), format("Valid", "20s"))
            else:
                print(format(cc, "20s"), format("Invalid", "20s"))
            num = (infile.readline().strip())
    
    main()
    

7 个答案:

答案 0 :(得分:1)

你忘了初始化num

def main():
    filename = input("What is the name of your input file? ")
    infile= open(filename,"r")
    # initialize num here
    num = cc = (infile.readline().strip())
    print(format("Card Number", "20s"), ("Valid / Invalid"))
    print("------------------------------------")
    while cc!= "EXIT":
        even = checkSecondDigits(num)
        odd = odd_digits(num)
        c_len = c_length(num)
        tot = even + odd

        if c_len == True and tot % 10 == 0:
            print(format(cc, "20s"), format("Valid", "20s"))
        else:
            print(format(cc, "20s"), format("Invalid", "20s"))
        num = cc = (infile.readline().strip())

答案 1 :(得分:0)

这是一个基于lunh算法

的非常简单的代码版本
def validator(n):

    validatelist=[]

    for i in n:
        validatelist.append(int(i))


    for i in range(0,len(n),2):


        validatelist[i] = validatelist[i]*2

        if validatelist[i] >= 10:

            validatelist[i] = validatelist[i]//10 + validatelist[i]%10


    if sum(validatelist)%10 == 0:
        print('This a valid credit card') 

    else:
        print('This is not valid credit card')

def cardnumber():

    result=''
    while True:
        try:
            result = input('Please enter the 16 digit credit card number : ')

            if not (len(result) == 16) or not type(int(result) == int) :
                raise Exception

        except Exception:    
            print('That is not a proper credit card number. \nMake sure you are entering digits not characters and all the 16 digits.')
            continue

        else:
            break


    return result

def goagain():
    return input('Do you want to check again? (Yes/No) : ').lower()[0] == 'y'

def main():

    while True:

        result = cardnumber()
        validator(result)


        if not goagain():
            break

if __name__ == '__main__':
    main()

答案 2 :(得分:0)

旧线程,但答案与我有关……而真正的问题尚未确定。 实际上,错误是当在主线中调用函数时,在将checkSecondDigits定义为参数的标识符/名称时,已使用参数的标识符(num)。该函数应在main()中通过以下方式调用 even = checkSecondDigits(cc),因此cc中的值(作为参数)被传递到num(作为参数)以在函数中使用。 相同的菜鸟错误是用奇数位和cc_length造成的。

这个问题(以及最初建议的答案)表明了将参数传递给参数的基本误解... 建议的“声明” num只是隐藏了此错误/误解,而且混淆了num(只能是本地)和cc(是全局)的局部和全局作用域,因此尽管在这种情况下建议有效,但它适用于错误的原因,糟糕的风格和不良的编程。

答案 3 :(得分:0)

进一步, num不应出现在main()中的任何地方,因为它应该是局部的(仅出现在被称为...的函数内部)。 该代码的最后一行应与第一行相同,但是最后一行错误地将数据分配给num而不是cc

cc = (infile.readline().strip())
print(format("Card Number", "20s"), ("Valid / Invalid"))
print("------------------------------------")
while cc!= "EXIT":
    even = checkSecondDigits(num)
    odd = odd_digits(num)
    c_len = c_length(num)
    tot = even + odd

    if c_len == True and tot % 10 == 0:
        print(format(cc, "20s"), format("Valid", "20s"))
    else:
        print(format(cc, "20s"), format("Invalid", "20s"))
    num = (infile.readline().strip())

答案 4 :(得分:0)

您可以使用我的代码进行卡验证,因为卡结构存储在CSV文件中,所以它是100%动态的,因此此处GitHub profilepython file link上的代码很容易更新, code explanation file linkCSV for datafile link

python代码:

# -*- coding: utf-8 -*-
"""
Created on Tue Sep 10 20:55:30 2019
@author: Preyash2047@gmail.com
"""


import csv
import numpy as np

#csv file imported and storf in reader
reader = csv.DictReader(open("card_data.csv"))

#input card number
card_number = input("Enter the card No: ")

#global variable declaration
min_digits=0
max_digits=0
card_number_list = list(card_number)
card_number_list_reverse=card_number_list[::-1]
card_number_length=len(card_number_list)
first_digit = int(card_number_list[0])

#global variable for final output
card_provider_list_number = 0
result_found = False
card_number_digits = 0
mit_name=""

#list
start=[]
end=[]
name=[]
c_d=[]
number_length=[]
min_max_digits_list=[]

#append the list from csv
for raw in reader:
    start.append(raw['start'])
    end.append(raw['end'])
    name.append(raw['name'])
    c_d.append(raw['c_d'])
    number_length.append(raw['number_length'])

#initialize the value of min_digits & max_digits
def min_max_digits():
    global min_digits
    global max_digits
    for i in range(len(start)):
        available_length=number_length[i].split(',')
        for j in range(len(available_length)):
            min_max_digits_list.append(available_length[j])
    min_max_digits_array = np.array(min_max_digits_list) 
    np.unique(min_max_digits_array)
    min_digits=int(min(min_max_digits_array))
    max_digits=int(max(min_max_digits_array))

#list to int
def list_to_int(noofdigits): 
    str1 = ""
    return int(str1.join(noofdigits))

#card validation
def iin_identifier():
    first_six_digit = list_to_int(card_number_list[0:6])
    for i in range(len(start)):
        if(first_six_digit >= int(start[i]) and first_six_digit <= int(end[i])):
            available_length=number_length[i].split(',')
            for j in range(len(available_length)):
                if(card_number_length == int(available_length[j])):
                    global card_provider_list_number
                    card_provider_list_number = i
                    global card_number_digits
                    card_number_digits = available_length[j]
                    global result_found
                    result_found = True

#Major Industry Identifier (MII) identification
def mit_identifier():
    global first_digit
    global mit_name
    switcher = { 
         1: "Airlines",
         2: "Airlines",
         3: "Travel and Entertainment",
         4: "Banking and Financial Services",
         5: "Banking and Financial Services",
         6: "Merchandising and Banking",
         7: "Petroleum",
         8: "Health care, Telecommunications",
         9: "National Assignment"
    }
    mit_name=switcher.get(first_digit, "MIT Identifier Not Found") 

#Luhn Algorithm or modulo-10 Algorithm
def luhn_algorithm():
    for i in range(card_number_length):
        if(i%2!=0 and i!=0):
            card_number_list_reverse[i]=int(card_number_list_reverse[i])*2
            #print(str(i)+" "+ str(card_number_list_reverse[i]))
            if(len(str(card_number_list_reverse[i]))==2):
                even_number_2=list(str(card_number_list_reverse[i]))
                card_number_list_reverse[i] = int(even_number_2[0])+int(even_number_2[1])
                #print("\tsubsum "+str(i)+" "+str(card_number_list_reverse[i]))
        else:
            card_number_list_reverse[i]=int(card_number_list_reverse[i])
    division_int = int(sum(card_number_list_reverse)/10)
    division_float=sum(card_number_list_reverse)/10
    if(division_int-division_float==0):
        return True

#initial level number length validation
def card_number_validation():
    min_max_digits()
    if(card_number_length>= min_digits and card_number_length <= max_digits and first_digit != 0):
        iin_identifier()
        mit_identifier()
        if(result_found and luhn_algorithm()):
            print("\nEntered Details are Correct\n")
            print("\nHere are the some details we know about you card")
            print("\nNo: "+card_number)
            print("\nIssuing Network: "+name[card_provider_list_number])
            print("\nType: "+c_d[card_provider_list_number]+" Card")
            print("\nCategory of the entity which issued the Card: "+mit_name)
        else:
            print("\nCard Number is Invalid\nPlease renter the number!\n")
    else:
        print("\nCard Number is Invalid\n")

#method called to run program
card_number_validation()

答案 5 :(得分:0)

n = input("Enter 16-digit Credit Card Number:")
lst = []
for i in range(16):
    lst.append(n[i])
# print(lst)
# list1 = n.split()
# print(list1)


def validate_credit_card():
    global lst
    if len(lst) == 16:
        for i in range(0, len(lst)):
            lst[i] = int(lst[i])
        # print(lst)
        last = lst[15]
        first = lst[:15]
        # print(first)
        # print(last)
        first = first[::-1]
        # print(first)
        for i in range(len(first)):
            if i % 2 == 0:
                first[i] = first[i] * 2
            if first[i] > 9:
                first[i] -= 9
        sum_all = sum(first)
        # print(first)
        # print(sum_all)
        t1 = sum_all % 10
        t2 = t1 + last
        if t2 % 10 is 0:
            print("Valid Credit Card")
        else:
            print("Invalid Credit Card!")
    else:
        print("Credit Card number limit Exceeded!!!!")
        exit()


if __name__ == "__main__":
    validate_credit_card()

答案 6 :(得分:-1)

首先,也许您应该删除多余的字符:

def format_card(card_num):
    """
    Formats card numbers to remove any spaces, unnecessary characters, etc
    Input: Card number, integer or string
    Output: Correctly formatted card number, string
    """
    import re
    card_num = str(card_num)
    # Regex to remove any nondigit characters
    return re.sub(r"\D", "", card_num)

使用Luhn算法检查信用卡是否有效后:

def validate_card(formated_card_num):
    """
    Input: Card number, integer or string
    Output: Valid?, boolean
    """
    double = 0
    total = 0

    digits = str(card_num)

    for i in range(len(digits) - 1, -1, -1):
        for c in str((double + 1) * int(digits[i])):
            total += int(c)
        double = (double + 1) % 2

    return (total % 10) == 0