1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* 采用 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位银行卡卡号的函数经笔者整理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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; } } |