PHP中关于银行卡号校验之luhn算法
算法介绍
Luhn算法(Luhn algorithm),也称为“模10”(Mod 10)算法,是一种简单的校验和算法,一般用于验证身份识别码,例如发卡行识别码、国际移动设备辨识码(IMEI),美国国家提供商标识号码,或是加拿大社会保险号码。该算法由IBM科学家Hans Peter Luhn创造,专利于1954年1月6日申请,1960年8月23日颁证,美国专利号2950048。该算法现已属于公有领域并得到了广泛的应用,例如ISO/IEC 7812-1。它不是一种安全的加密哈希函数,设计它的目的只是防止意外出错而不是恶意攻击。
优缺点
luhn算法将检测任何单位错误,以及几乎所有相邻数字的转置。但是,它不会检测到两位数序列09到90的转置(反之亦然)。它将检测10个可能的双误差中的7个(它不会检测到22↔55,33↔66或44↔77)。其他更复杂的校验位算法(例如Verhoeff算法和Damm算法)可以检测更多的转录错误。 Luhn mod N算法是支持非数字字符串的扩展。
因为算法以从右到左的方式对数字进行操作,并且零位仅在它们导致位置偏移时影响结果,所以零填充数字串的开头不会影响计算。因此,填充到特定位数的系统(例如,通过将1234转换为0001234)可以在填充之前或之后执行Luhn验证并获得相同的结果。
在0到奇数长度之前,可以从左到右而不是从右到左处理数字,使奇数位数加倍。
该算法出现于美国专利 【N.y. Computer for verifying numbers:, US 2950048 A[P]. 1960.】中,用于计算校验和的手持式机械设备。因此需要相当简单。该装置通过机械手段获得了模数10。替换数字,即double和reduce过程的结果,不是机械地产生的。相反,数字在机器的主体上以其置换顺序标记。
算法原理
- 从最后一位开始逆向计算奇数位相加之和
- 从最后一位开始逆向将偶数位先乘2如果乘积为2位数则减去9再求和、如果乘积不是2位数则直接相加
- 将奇数位与偶数位相加得到总和
- 如果能被10整除则是合法的银行卡号
实现代码示例
/** * 检查银行卡号是否正确 * @param string $cardNumber * @return bool */ function checkBankCardNumber($cardNumber = '') { if (empty($cardNumber) || !is_numeric($cardNumber)) { return false; } $length = strlen($cardNumber); $allNumber = []; $sumOdd = 0; $sumEven = 0; //将所有数字分隔开来塞进临时数组 for ($i = 0;$i < $length;$i++) { $allNumber[] = substr($cardNumber, $length-$i-1, 1); } for ($k = 0; $k < $length; $k++) { if ($k % 2 == 0) { $sumOdd += $allNumber[$k]; } else { if ($allNumber[$k] * 2 >= 10) { $sumEven += $allNumber[$k] * 2 - 9; } else { $sumEven += $allNumber[$k] * 2; } } }
$result = $sumOdd + $sumEven; return $result % 10 == 0 ? true : false; } var_dump(checkBankCardNumber('6214xxxxx7937886')); //左边传入了一个正确的招行卡号效验通过,打印为true值
END.

浙公网安备 33010602011771号