Generating fake credit card numbers
hacking
In a follow-up article, I’ll describe another amusing utilization of card number generators.
Theory
Credit card numbers have structure. They can essentially be decomposed into three parts:
- An issuer identification number (IIN) consisting of 6 (sometimes 8) digits
- An individual account identifier
- A single digit checksum known as the check digit
The total length of a card number will depend on the issuer, ranging from 12 to 19. We will call payload the set of all the digits except the checksum (IIN and account identifier). For most of the credit cards out there, the checksum is calculated from the payload using the Luhn algorithm, also known as the mod 10 algorithm. The idea is that a particular computation involving all the digits of the card number should be divisible by ten for the card number to be considered valid, hence the name. We are going to restrict ourselves to American Express, Mastercard and Visa, which all use a mod 10 check digit.
Generation
If you read this article, you will notice that the IIN can contain lots of information, depending on the issuing network. But most of the time, credit card number validators will only perform a Luhn test, and will sometimes check that the IIN is within the right range for the issuer specified by the user. So in practice we won’t care about the IIN substructure, as we only need to select an IIN within the appropriate range. This means that only a few digits of the IIN must be chosen carefully according to the issuer, and all the rest of the payload is chosen at random. You can find a complete list of IIN ranges and card number lengths per issuer here, but for the three types of cards we want to fake, here’s how it goes:
ISSUER IIN PREFIX LENGTH
American Express 34 | 37 15
Mastercard 51 - 55 16
Visa 4 13 | 16
So for example, to generate a valid American Express payload, we could start by
In order to calculate the check digit using the Luhn algorithm, we will consider the digits of the payload
We will replace each second digit
with
The last modulo 10 operation is important, as
Example
Say we want to generate an American Express card number. Then
Then
Validation
Now, to validate a credit card number
- You can remove the check digit
from the card number to obtain , recompute the checksum as above, and check that you obtain the same digit (boring). - Or you can extract
as above, compute using and check that is divisible by 10.
Example
Here is an example with my credit card number (kidding):
Or alternatively:
so the card number is valid.
Practice
Here is a Python implementation of a card number generator. First, let’s write a helper function luhn_sum()
that computes the number
import random
import sys
import string
def luhn_sum(digits):
s = 0
for idx, digit in enumerate(map(int, digits)):
mu = 1 if idx % 2 else 2
n = mu * digit
s += n - 9 if n > 9 else n
return s
Here, we used the fact that every number
Then, we just need to construct the payload, and compute the check digit using luhn_sum()
and
def generate_card(issuer):
prefixes = {
"americanexpress": [34, 37],
"mastercard": list(range(51, 56)),
"visa": [4]
}
lengths = {
"americanexpress": [15],
"mastercard": [16],
"visa": [13, 16]
}
if not issuer in prefixes.keys():
raise Exception("Unknown issuer")
# Get a prefix and a card number length at random
prefix = str(random.choice(prefixes[issuer]))
length = random.choice(lengths[issuer])
# Generate a random body
body_length = length - len(prefix) - 1
body = ''.join(random.choice(string.digits)
for _ in range(body_length))
# Concatenate prefix and body
payload = prefix + body
# Calculate the check digit using Luhn's algorithm
s = luhn_sum(payload[::-1])
c = (10 - s % 10) % 10
# Concatenate check digit
return payload + str(c)
The length of a Visa credit card number can be either
A Luhn check can be implemented this way:
def luhn_check(card_number):
c = int(card_number[-1])
s = luhn_sum(card_number[len(card_number)-2::-1])
return (s + c) % 10 == 0
You can check the card numbers produced by the above code with online validators such as this one, and see for yourself that it works.