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过程的结果,不是机械地产生的。相反,数字在机器的主体上以其置换顺序标记。
 

算法原理

  1. 从最后一位开始逆向计算奇数位相加之和
  2. 从最后一位开始逆向将偶数位先乘2如果乘积为2位数则减去9再求和、如果乘积不是2位数则直接相加
  3. 将奇数位与偶数位相加得到总和
  4. 如果能被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.

posted @ 2021-07-08 20:11  不进腾讯不改名  阅读(514)  评论(0)    收藏  举报