Skip to content

Instantly share code, notes, and snippets.

@wrboyce
Created August 16, 2011 13:52
Show Gist options
  • Select an option

  • Save wrboyce/1149132 to your computer and use it in GitHub Desktop.

Select an option

Save wrboyce/1149132 to your computer and use it in GitHub Desktop.
import random
class CreditCard(object):
CARD_TYPES = {
'amex': {
'prefixes': ['34', '37'],
'length': [15]
},
'diners-carte-blance': {
'prefixes': [300, 301, 302, 304, 305],
'length': [14],
},
'diners-international': {
'prefixes': [36],
'length': [14]
},
'diners-uscanada': {
'prefixes': [54, 55],
'length': [16]
},
'discover': {
'prefixes': ['6011'] + [str(i) for i in range(622126,622926)] + ['644', '645', '646', '647', '648', '649', '65'],
'length': [16]
},
'jcb': {
'prefixes': [str(i) for i in range(3528,3590)],
'length': [16]
},
'laser': {
'prefixes': ['6304', '6706', '6771', '6709'],
'length': range(16, 20)
},
'maestro': {
'prefixes': ['5018', '5020', '5038', '6304', '6759', '6761', '6762', '6763'],
'length': range(12, 20)
},
'mastercard': {
'prefixes': ['51', '52', '53', '54', '55'],
'length': [16]
},
'solo': {
'prefixes': ['6334', '6767'],
'length': [16, 18, 19]
},
'switch': {
'prefixes': ['4903', '4905', '4911', '4936', '564182', '633110', '6333', '6759'],
'length': [16, 18, 19]
},
'visa': {
'prefixes': ['4'],
'length': [16]
},
'visa-electron': {
'prefixes': ['4026', '417500', '4508', '4844', '4913', '4917'],
'length': [16]
}
}
def __init__(self, type=None):
type = type.lower()
if not type in CreditCard.CARD_TYPES.keys():
type = None
if not type:
type = random.choice(CreditCard.CARD_TYPES.keys())
self.type = type
def _as_int(self, list):
return [int(i) for i in list]
def generate(self):
# Pick a length & a prefix
length = random.choice(CreditCard.CARD_TYPES[self.type]['length'])
result = random.choice(CreditCard.CARD_TYPES[self.type]['prefixes'])
# Pad the number out to len-1 with random digits
result += ''.join(str(random.choice(range(10))) for i in range(length-len(result)-1))
# Generate the check digit, see http://en.wikipedia.org/wiki/Luhn_algorithm for what is going on here
total = sum(self._as_int(result[-2::-2])) + sum(self._as_int(''.join([str(i*2) for i in self._as_int(result[::-2])])))
check_digit = ((total / 10 + 1) * 10 - total) % 10
return '%s%s' % (result, check_digit)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment