We have learned to code simple crontab using python and I believe that should have encouraged you to try your own idea as Python code. In this article, I have written small Python function to perform payment card check digit verification.
Before we start discussing the python function, Let me give you some high-level information about the card check digit project.
In payment card industries (PCI), the Card number is important/secured information to store or handle in the applications. As you all know that, we should not disclose our credit/debit/prepaid card information to any of third parties for any reason unless until it is solely for making payments. In the same importance or governance will be required for the organization that supports or provide banking operation on behalf of banks, Financial institution and global payment &technology providers.
In simple term, these all are coming under PCI compliance certificate for merchants of all sizes, financial institutions, point-of-sale vendors, and hardware and software developers who create and operate the global infrastructure for processing payments. So every bank/FI can provide their project to the vendors who are PCI certified in order to make a trust that PAI (personal account information) of cardholder/customer will be handled in a secure manner.
Further, in order to obtain this PCI certificate, some organization engage their internal information security team to review the systems, logs, applications & microservices to ensure the PAI information not leaked. This verification will happen for the certain period of time or on every software releases.
Now, In order to verify whether the clear card numbers are either stored on some unsafe location or logs or even in the emails. There should be an auto scan scheduled on servers to scan the card numbers and throw the notification if anything found.
The payment card number that we see as 16 digit number in our debit/credit/prepaid cards are generated using Luhn algorithm or also known as “modulus 10” algorithm. We will discuss the algorithm while we do code below.
The idea is to have simple UI to get the user input card number and return whether it is card number or not. I am going to use Tkinter python module and more of play with python list data structure.
Simple Tkinter program:
First, we need to import the module for our project,
from Tkinter import * --I wanted to import all the submodule of Tkinter.
Next, we need to define our UI Tkinter label
w = Tk() -- Creating Tkinter object Label(w, text="Enter 16 digit number:").pack() --defining our label with pack
With the “w” Tkinter object, I have formed the simple label with text and wrapped that label with a pack() method to geometrically position my text whether to be displayed on the top or on the side.
Label(w, text="Your Expression:").pack() --defualt is top
Label(w, text="Your Expression:").pack(side = "left")
After the label creation, we should define the Entry() widgets for our Tkinter object “W” and assign to entry variable.
Now the entry variable is bind with our return statement of function card_check_digit which is the core of this project. This entry variable has object reference of pack() method which can be called to combine our text variable to pass it as the parameter to our bound function card_check_digit.
entry = Entry(w) entry.bind("<Return>", card_check_digit) entry.pack()
Simple Check digit Function:
Define our own function name card_check_digit with parameter as card number to perform check digit. We are going to declare the odd & even list, get the card number, slice each digit of card number as an int.
def card_check_digit(card): --":" to start our function card_even= card_odd= card_number = entry.get() card_list_var = list(card_number) --Converting the string to list card_list = map(lambda x:int(x),card_list_var) --Convert the values from string to int in list
Here, I wanted to use the list mutable object to play around with payment card number. The values that received from the Tkinter button entry.get(), is converted into list data structure as shown above. Then the list object passed into python map function in order fetch each value of the list to convert an int value of card_list.
Map() function is used to apply any lambda/user-defined/pre-defined function on each and every value of sequence type data structures such as list, tuple, set,etc.
In order to perform our Luhn approach, we have ignored the last digit of the given card number by slicing the card_list values having only 0-15 position into the card_to_test list.
card_to_test = card_list[0:15]
Next step is to reverse the list values.
Next, I wanted to insert ‘0’ in the 0th position of the list in order to segregate the even & odd digits for further odd digits to multiply with 2 as per 4th step of Luhn algorithm.
card_to_test.insert(0,0) -- Insert 0 on 0th position in the List. map(lambda x,y:card_even.append(int(x)) if y % 2 == 0 else card_odd.append(int(x)),card_to_test, range(len(card_to_test))) card_odd_2 = map(lambda x: int(x)*2,card_odd)
again Map() is the wonderful function to shorten your code and achieve more. As you can see above, the card_to_test list values have been passed as “X” and range(card_to_test) list values passed as “Y” to find the odd & even position using mod 2 formula.
range: Range is the python inbuilt function which creates integer list.
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> type(range(10)) --Create the list <type 'list'> >>> type(range(10)) --ensure the integer values in the list. <type 'int'>
Lambda: Lambda is used to define your own anonyms function. The concept of Lambda has used widely across the technologies also like Amazon Lambda (serverless service). But it is well used in conjunction with typical functional concepts like,
reduce()Using which you can have your anonyms function defined and applied on the values. As you seen in the above code, Lambda declared with two variables X & Y followed by “:” action of what should be done with logic, as here my logic is to perform two actions either add values to card_even list or add values to card_odd based on the IF condition y % 2 (position of card_to_test is odd or even) and act accordingly. This iteration will happen until the Map() function get values from both card_to_test & range(card_to_test) list.
After I got my even & odd digits as list card_even & card_odd. One more Mapper iteration on card_odd to multiply the values with 2 as per Luhn algorithm. The further step is to subtract with 9 if any number goes more than 9, to sum all the numbers and arrive at a final value.
card_over_nine = map(lambda x: x if x < 9 else (x - 9), card_odd_2) --Same way as it is descibed in previous line of code. tot_odd = sum(card_over_nine) tot_even = sum(map(lambda x: int(x),card_even)) final = tot_odd+tot_even
As you can see above, the card_over_nine list created based on mapper performed on card_odd_2 with the simple logic of values in card_odd_2 greater than 9, if so do subtraction. with the final value, we have to do verification of whether the last digit match with formula 10 – final % 10.
last_val = 10 - final % 10
We are now final value to match with the last digit of card number which we ignored in the first step. So with matching criteria, the IF logic performed and response passed to Tkinter label which then packed with pack() function to show on the Tkinter small UI as below,
if last_val==card_last: res.configure(text = "You card is valid for payment") else: res.configure(text = "This is not payment card number")
The control flow forwarded to the main loop of Tkinter for continues monitoring the user input.
res = Label(w) res.pack() w.mainloop()
Let’s test this code first with some random 16 digit number and actual payment card (I have to mask my card as I cannot publish with full digit),
Hope this walkthrough about card_check_digit gives some high level of understanding about how the online payments systems are making basic validation of card number and technical details of python List, Map(), Lambda, range & little bit Tkinter modules. If you required further understanding about the code that discussed in this forum, you can comment over here and we will chat.