There are three parts to the validation of the card number:
- PATTERN - does it match an issuers pattern (e.g. VISA/Mastercard/etc.)
- CHECKSUM - does it actually check-sum (e.g. not just 13 random numbers after "34" to make it an AMEX card number)
- REALLY EXISTS - does it actually have an associated account (you are unlikely to get this without a merchant account)
Pattern
- MASTERCARD Prefix=51-55, Length=16 (Mod10 checksummed)
- VISA Prefix=4, Length=13 or 16 (Mod10)
- AMEX Prefix=34 or 37, Length=15 (Mod10)
- Diners Club/Carte Prefix=300-305, 36 or 38, Length=14 (Mod10)
- Discover Prefix=6011,622126-622925,644-649,65, Length=16, (Mod10)
- etc. (detailed list of prefixes)
Checksum
Most cards use the Luhn algorithm for checksums:
Luhn Algorithm described on Wikipedia
There are links to many implementations on the Wikipedia link, including PHP:
<?
/* Luhn algorithm number checker - (c) 2005-2008 shaman - www.planzero.org *
* This code has been released into the public domain, however please *
* give credit to the original author where possible. */
function luhn_check($number) {
// Strip any non-digits (useful for credit card numbers with spaces and hyphens)
$number=preg_replace('/D/', '', $number);
// Set the string length and parity
$number_length=strlen($number);
$parity=$number_length % 2;
// Loop through each digit and do the maths
$total=0;
for ($i=0; $i<$number_length; $i++) {
$digit=$number[$i];
// Multiply alternate digits by two
if ($i % 2 == $parity) {
$digit*=2;
// If the sum is two digits, add them together (in effect)
if ($digit > 9) {
$digit-=9;
}
}
// Total up the digits
$total+=$digit;
}
// If the total mod 10 equals 0, the number is valid
return ($total % 10 == 0) ? TRUE : FALSE;
}
?>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…