## I.T. Security and Linux Administration

Oct 29 2012   11:37AM GMT

# [Python] Check to see if a number passes as a credit card

Profile: Eric Hansen

Last month I went over a series of articles on how to use Balanced Payments to handle credit card processing in Python.  This time, continuing on with the credit card processing, I’m going to provide a small script that will show you how to validate a number as a credit card number.

This can’t be used to buy something with false credit card information, but was a fun little side project I decided to work on, and thought I would share.

Requirements

Unlike most of my scripts I’ve been posting on here, there are no special requirements to do this.  However, basic understanding of math and Python helps in this, a lot.

Background

Essentially credit card numbers are generated by a mod-10 algorithm, also called the Luhn Algorithm.  The basic idea behind this process is that the last digit is the checksum, and the rest of the data is ultimately added together.  If the sum of the digits equals the checksum digit, everything checks out.  Otherwise, the number isn’t valid.

The Code

As always I will be posting the full script at the end of this page, but I will be breaking it down block by block.

test_data = “38520000023237”

# The last digit of the number is the checksum
checksum = test_data[-1:]

# Get the rest of the data
data = test_data[0:-1]

# We have to double every even digit from right-to-left, so we reverse the string of digits
data_rev = data[::-1]

‘test_data’ is just a variable I set to provide a number that will validate correctly.  Then we get the checksum, or the last digit, and store the rest of the digits in another variable.

We reverse the data because the Luhn algorithm requires working from right to left.  So doing this just makes it a lot easier for me, personally.

val = 0
i = 0
datastr = “”

Initializing variables makes it better than re-declaring a variable over and over again (these will be used in a while() loop).  ‘datastr’ will hold the new digits (the next code block will make this sentence sound more sane).

# Loop through each digit
while i < len(data_rev):
# If (i % 2) == 0, we’re at an even position in the buffer stream
if i % 2 == 0:
# Get the digit at the current spot, then double it
val = int(data_rev[i])
val *= 2

# If ‘val’ is a double-digit, we need to sum up both digits (i.e.: 18 = 1+8 = 9)
if val >= 10:
val = str(val)
val = int(val[0]) + int(val[1])
else:
val = val[0]

# Add the new value to the stream
datastr = “%s%s” % (datastr, str(val))
else:
datastr = “%s%s” % (datastr, data_rev[i])

i += 1

WordPress’ stock formatting of code is ugly (which is one reason why I offer the script at the end), but all of this is wrapped inside of the while() loop.  The  code itself is self-explanatory thanks to my wonderful commenting.  But essentially if the current position in the buffer is even (i % 2 = 0), then we double the current digit at said position.  If the result is more than 9, then we have to add up both digits (i.e.: 23 = 2+3 = 5), and that is our new value.  We then append the new number to the datastr.  I know you can also do this as datastr += val but I don’t like the way that looks.  So, I don’t do it that way.

i = 0
j = 0

More counters for the next while() loop…there are a few in this, which is slightly surprising to me.

# Now we need to get the sum of all the digits
while i < len(datastr):
j += int(datastr[i])
i += 1

Again that is inside of the while() loop.  We have to add up all the digits we got in the last while() loop, so that is what ‘j’ is equal to.

# Multiply the total sum by 9, then get the final digit of the product
i = j * 9
i = str(i)
i = i[-1:]

Here we multiply the final sum by 9 (no idea why the algorithm calls for this, but it’s part of the process), and get the last digit (similar to the beginning of this process).

# If the last digit of the product above matches the last digit of the original number, success
if i == checksum:
print “Success”
else:
print “Failure”

If the last digit in the above string of digits is the same as the checksum of the original number, we’re good to go (a valid credit card number).

Code

You can view the whole file here: https://github.com/SecurityForUs/PythonUtils/blob/master/luhnalgo.py