您的位置:寻梦网首页编程乐园PHP 编程>信用卡号码规则和校验方法(含PHP代码)
信用卡号码规则和校验方法(含PHP代码)
(转自《PHP 5 in Practice中文版》)

11.5 信用卡号码
商业站点需要处理信用卡号码。信用卡公司已经在卡号里建立了校验体系。在把信用卡号码标准化为不包含空格的数字字符串之后,可以进行两方面的检验。

首先,不同信用卡公司遵循特定的编号规则。

n Visa:以4开头,共有13位或16位数字。

n MasterCard:以51~56开头,共有16位数字。

n American Express:以34或37开头,共有15位数字。

n Discover:以6011开头,共有16位数字。

另外,所有卡号还要遵循称为“Mod 10”的算法,它可以用来判断某个号码是否属于有效的信用卡号码。它的工作方式是这样的:首先颠倒数字的次序,接着每隔一个数字把数字乘以2,然后把所有的数字加起来;但如果相乘结果大于等于10,就要把这个结果的个位和十位的数字加起来。例如数字7,乘以2以后是14,所以它对应的数字应该是 1+4=5。在所有数字相加之后,其结果应该能够被10整除。上述这些规则都写入了程序清单11.5.1包含的函数里。

程序清单11.5.1 信用卡号码函数库

<?php

// A function that will accept and clean up CC numbers

function standardize_credit($num) {

// Remove all non-digits from the string

return preg_replace('/[^0-9]/', '', $num);

}

// A function to check the validity of a CC number

// It must be provided with the number itself, as well as

// a character specifying the type of CC:

// m = Mastercard, v = Visa, d = Discover, a = American Express

function validate_credit($num, $type) {

// First perform the CC specific tests:

// Store a few evaluations we will need often:

$len = strlen($num);

$d2 = substr($num,0,2);

// If Visa must start with a 4, and be 13 or 16 digits long:

if ( (($type == 'v') && (($num{0} != 4) ||

!(($len == 13) || ($len == 16)))) ||

// If Mastercard, start with 51-56, and be 16 digits long:

(($type == 'm') && (($d2 < 51) ||

($d2 > 56) || ($len != 16))) ||

// If American Express, start with 34 or 37, 15 digits long:

(($type == 'a') && (!(($d2 == 34) ||

($d2 == 37)) || ($len != 15))) ||

// If Discover: start with 6011 and 16 digits long

(($type == 'd') && ((substr($num,0,4) != 6011) ||

($len != 16))) ) {

// Invalid card:

return false;

}

// If we are still here, then time to manipulate and do the Mod 10

// algorithm. First break the number into an array of characters:

$digits = str_split($num);

// Now reverse it:

$digits = array_reverse($digits);

// Double every other digit:

foreach(range(1, count($digits) - 1, 2) as $x) {

// Double it

$digits[$x] *= 2;

// If this is now over 10, go ahead and add its digits, easier since

// the first digit will always be 1

if ($digits[$x] > 9) {

$digits[$x] = ($digits[$x] - 10) + 1;

}

}

// Now, add all this values together to get the checksum

$checksum = array_sum($digits);

// If this was divisible by 10, then true, else it's invalid

return (($checksum % 10) == 0) ? true : false;

}

// Check various credit card numbers:

$nums = array(

'344 2345 3466 4577' => 'a', '3794 2345 3466 4577' => 'a',

'4938748398324' => 'v', '4123-1234-5342' => 'v',

'51847293 84567434' => 'm', '5723x2345x2345x6161' => 'm',

'6011 6011 6011 6011' => 'd', '6012 392563242423' => 'd',

);

foreach ($nums as $num => $type) {

$st = standardize_credit($num);

$valid = validate_credit($st, $type);

$output = $valid ? 'Valid' : 'Invalid';

echo "<p>{$st} - {$type} = {$output}</p>\n";

}

?>