/* 采用 Luhm 校验方法计算:
1,将未带校验位的 15 位卡号从右依次编号 1 到 15,位于奇数位号上的数字乘以 2
2,将奇位乘积的个十位全部相加,再加上所有偶数位上的数字
3,将加法和加上校验位能被 10 整除。
*/
function luhm($s) {
$n = 0;
for ($i = strlen($s); $i >= 1; $i--) {
$index=$i-1;
//偶数位
if ($i % 2==0) {
$n += $s{$index};
} else {//奇数位
$t = $s{$index} * 2;
if ($t > 9) {
$t = (int)($t/10) + $t%10;
}
$n += $t;
}
}
return ($n % 10) == 0;
}
网上盛传一个采用Luhm校验方法对银行卡卡号进行效验的函数,据笔者测试发现,该函数只能效验16位银行卡卡号,无法效验19位的银行卡卡号,能够效验19位银行卡卡号的函数经笔者整理如下:
function luhm($bankNo) {
// 奇数之和
$sumOdd = 0;
// 偶数之和
$sumEven = 0;
// 长度
$length = strlen($bankNo);
$wei = [];
for ($i = 0; $i < $length; $i++) {
$wei[$i] = substr($bankNo, $length - $i - 1, 1);// 从最末一位开始提取,每一位上的数值
}
for ($i = 0; $i < $length / 2; $i++) {
$sumOdd += $wei[2 * $i];
if(!isset($wei[2 * $i + 1])) continue;// 如果为19位卡号,要防止报Notice: Undefined offset错误
if (($wei[2 * $i + 1] * 2) > 9)
$wei[2 * $i + 1] = $wei[2 * $i + 1] * 2 - 9;
else
$wei[2 * $i + 1] *= 2;
$sumEven += $wei[2 * $i + 1];
}
if (($sumOdd + $sumEven) % 10 == 0) {
return true;
} else {
return false;
}
}
信用卡也同样有效吗?
应该也有效,但没测试过。