The credit/debit card number is referred to as a **PAN**, or *Primary Account Number*. The first six digits of the PAN are taken from the **IIN**, or *Issuer Identification Number*, belonging to the issuing bank (IINs were previously known as BIN — Bank Identification Numbers — so you may see references to that terminology in some documents). These six digits are subject to an international standard, ISO/IEC 7812, and can be used to determine the type of card from the number.

Unfortunately the actual ISO/IEC 7812 database is not publicly available, however, there are unofficial lists, both commercial and free, including on Wikipedia.

Anyway, to detect the type from the number, you can use a regular expression like the ones below: Credit for original expressions

**Visa:** `^4[0-9]{6,}$`

Visa card numbers start with a 4.

**MasterCard:** `^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$`

Before 2016, MasterCard numbers start with the numbers 51 through 55, **but this will only detect MasterCard credit cards**; there are other cards issued using the MasterCard system that do not fall into this IIN range. In 2016, they will add numbers in the range (222100-272099).

**American Express:** `^3[47][0-9]{5,}$`

American Express card numbers start with 34 or 37.

**Diners Club:** `^3(?:0[0-5]|[68][0-9])[0-9]{4,}$`

Diners Club card numbers begin with 300 through 305, 36 or 38. There are Diners Club cards that begin with 5 and have 16 digits. These are a joint venture between Diners Club and MasterCard and should be processed like a MasterCard.

**Discover:** `^6(?:011|5[0-9]{2})[0-9]{3,}$`

Discover card numbers begin with 6011 or 65.

**JCB:** `^(?:2131|1800|35[0-9]{3})[0-9]{3,}$`

JCB cards begin with 2131, 1800 or 35.

Unfortunately, there are a number of card types processed with the MasterCard system that do not live in MasterCard’s IIN range (numbers starting 51...55); the most important case is that of Maestro cards, many of which have been issued from other banks’ IIN ranges and so are located all over the number space. As a result, **it may be best to assume that any card that is not of some other type you accept must be a MasterCard**.

**Important**: card numbers do vary in length; for instance, Visa has in the past issued cards with 13 digit PANs and cards with 16 digit PANs. Visa’s documentation currently indicates that it may issue or may have issued numbers with between 12 and 19 digits. **Therefore, you should not check the length of the card number, other than to verify that it has at least 7 digits** (for a complete IIN plus one check digit, which should match the value predicted by the Luhn algorithm).

One further hint: **before processing a cardholder PAN, strip any whitespace and punctuation characters from the input**. Why? Because it’s typically *much* easier to enter the digits in groups, similar to how they’re displayed on the front of an actual credit card, i.e.

```
4444 4444 4444 4444
```

is much easier to enter correctly than

```
4444444444444444
```

There’s really no benefit in chastising the user because they’ve entered characters you don't expect here.

**This also implies making sure that your entry fields have room for ***at least* 24 characters, otherwise users who enter spaces will run out of room. I’d recommend that you make the field wide enough to display 32 characters and allow up to 64; that gives plenty of headroom for expansion.

Here's an image that gives a little more insight:

**UPDATE (2016):** Mastercard is to implement new BIN ranges starting Ach Payment.

There's a function in the **standard-library** for this: `itertools.permutations`

.

```
import itertools
list(itertools.permutations([1, 2, 3]))
```

If for some reason you want to implement it yourself or are just curious to know how it works, here's one nice approach, taken from http://code.activestate.com/recipes/252178/:

```
def all_perms(elements):
if len(elements) <=1:
yield elements
else:
for perm in all_perms(elements[1:]):
for i in range(len(elements)):
# nb elements[0:1] works in both string and list contexts
yield perm[:i] + elements[0:1] + perm[i:]
```

A couple of alternative approaches are listed in the documentation of `itertools.permutations`

. Here's one:

```
def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = range(n)
cycles = range(n, n-r, -1)
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
```

And another, based on `itertools.product`

:

```
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
for indices in product(range(n), repeat=r):
if len(set(indices)) == r:
yield tuple(pool[i] for i in indices)
```

## Best Answer

After some research, I think I'll go with the

ISO 7064 Mod 97,10formula. It seems pretty solid as it is used to validate IBAN (International Bank Account Number).The formula is very simple:

`123456`

`mod(98 - mod(number * 100, 97), 97)`

=> 76`mod(code, 97) == 1`

Test :

`mod(12345676, 97) = 1`

=> GOOD`mod(21345676, 97) = 50`

=> BAD !`mod(12345678, 97) = 10`

=> BAD !Apparently, this algorithm catches most of the errors.

Another interesting option was the Verhoeff algorithm. It has only one verification digit and is more difficult to implement (compared to the simple formula above).