For various reasons I’ve needed to validate some credit card numbers in Python. For future reference, here’s what I’ve come up with:
import re def validate_cc(s): """ Returns True if the credit card number ``s`` is valid, False otherwise. Returning True doesn't imply that a card with this number has ever been, or ever will be issued. Currently supports Visa, Mastercard, American Express, Discovery and Diners Cards. >>> validate_cc("4111-1111-1111-1111") True >>> validate_cc("4111 1111 1111 1112") False >>> validate_cc("5105105105105100") True >>> validate_cc(5105105105105100) True """ # Strip out any non-digits # Jeff Lait for Prime Minister! s = re.sub("[^0-9]", "", str(s)) regexps = [ "^4\d{15}$", "^5[1-5]\d{14}$", "^3[4,7]\d{13}$", "^3[0,6,8]\d{12}$", "^6011\d{12}$", ] if not any(re.match(r, s) for r in regexps): return False chksum = 0 x = len(s) % 2 for i, c in enumerate(s): j = int(c) if i % 2 == x: k = j*2 if k >= 10: k -= 9 chksum += k else: chksum += j return chksum % 10 == 0

