Python 信用卡验证

Python Credit Card Validation

我是初学者 Python 学习者,我目前正在使用 Luhn 算法来检查信用卡验证。我写了大部分代码,但我遇到了 2 个错误,第一个错误是在赋值之前引用了 num。我得到的第二个是“_io.TextIOWrapper”类型的对象没有 len()。进一步的帮助/指导将不胜感激。

这些是 Luhn 算法(Mod10 校验)的步骤

  1. 从右到左每第二个数字加倍。如果这个“加倍”的结果是两位数,加上两位数 number 得到一个数字。
  2. 现在将第 1 步中的所有个位数相加。
  3. 将信用卡号中奇数位的所有数字从右到左相加。
  4. 将第 2 步和第 3 步的结果相加。
  5. 如果第4步的结果能被10整除,则卡号有效;否则无效。

我的输出应该是这样的

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()

你只是忘了初始化 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())

这是一个非常简单的代码版本,它基于 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()

旧线程,但答案与我有关...并且未确定真正的问题。 实际上,错误是您在主线调用函数时将 checkSecondDigits 定义为参数的 identifier/name 时使用了参数的标识符(num)。该函数应在 main() 中调用 even = checkSecondDigits(cc) 因此 cc 中的值(即参数)被传递到 num(作为参数)以在函数内使用。 odd_digits 和 cc_length.

也犯了同样的菜鸟错误

这个问题(以及最初建议的答案)展示了对将参数传递给参数的根本误解... num 的建议 'declaring' 只是隐藏了这个 error/misunderstanding 并且还混淆了 num (应该只是本地的)和 cc (应该是全局的)的本地和全局范围,所以虽然建议在这种情况下有效,它的工作原因错误,风格和编程都很糟糕。

此外, 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())

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

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

您可以使用我的代码进行卡片验证,它是 100% 动态的,因为卡片结构存储在 CSV 文件中,因此很容易在此处更新 GitHub profile, python file link, code explanation file link and CSV 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()
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()