PHP效验银行卡卡号

/* 采用 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;
	}
}