QT C++ Luhn算法验证银行卡号合法性

项目需要找了比较多银行卡的校验方法,发现很多博客的校验方法写的不清不楚乱七八糟,有的连算法的名字都写错了(写成Luhm算法的都有ヽ(#`Д´)ノ),不知道是不是从其他网站直接复制过去的,在这里把自己已经验证成功的方法写下来,避免大家再次踩坑。

Luhn算法定义(来自维基百科):

Luhn算法(Luhn algorithm),也称为“模10”(Mod 10)算法,是一种简单的校验和算法,一般用于验证身份识别码,例如发卡行识别码、国际移动设备辨识码(IMEI),美国国家提供商标识号码,或是加拿大社会保险号码。该算法由IBM科学家Hans Peter Luhn创造,专利于1954年1月6日申请,1960年8月23日颁证,美国专利号2950048。

该算法现已属于公有领域并得到了广泛的应用,例如ISO/IEC 7812-1。它不是一种安全的加密哈希函数,设计它的目的只是防止意外出错而不是恶意攻击。

Luhn算法释义(来自维基百科):

Luhn算法会通过校验码对一串数字进行验证,校验码通常会被加到这串数字的末尾处,从而得到一个完整的身份识别码。

我们以数字“7992739871”为例,计算其校验位:

从校验位开始,从右往左,偶数位乘2(例如,7*2=14),然后将两位数字的个位与十位相加(例如,10:1+0=1,14:1+4=5);
把得到的数字加在一起(本例中得到67);
将数字的和取模10(本例中得到7),再用10去减(本例中得到3),得到校验位。

原始数字7992739871x
偶数位乘2718947691672x
将数字相加7994769772=67

我国的银行卡号码基本上都是符合Luhn算法的,四大行就不用说了,我用比较小的银行测试也可以通过校验,所以只要是常规银行卡我觉得都可以用这个算法去检测合法性。

我用到的算法和维基百科上稍微有些不同(或者说是维基百科上写的不太好),其中,原始数字最后一位应该是表格中的X,所谓的将偶数位乘以2,是去掉校验数X之后开始算的。

维基百科里面的:偶数位乘2,然后将两位数字的个位与十位相加这一条,代码上可以写成:如果偶数位数字乘以2如果大于9则将结果减去9。

最后一步,改成,将得到的数字加在一起,再与校验数字相加,得到的最后结果如果对10取模等于0,则视为合法。

逻辑变形为:

1、取银行卡号码最后一位为校验数;

2、除校验位外,从右往左,偶数乘以2,如果得到的数字大于9则减去9;

3、将经过步骤2处理过的所有数字相加(包括奇数位、偶数位、校验位);

4、对10取模,如果结果为0则为合法。

写成代码如下:

/**
* @brief    Luhn算法验证银行卡号
* @para     cardNum:银行卡号
* @author   Andy
* @date     2019-03-19
*/
bool checkBankCard(QString cardNum){
    int xCheck = cardNum.right(1).toInt();
    cardNum = cardNum.left(cardNum.size() - 1);
    int size = cardNum.length();
    if (size > 19) return false;
    int sum = 0;
    for(int n = size; n > 0; n--) {
        int value = cardNum.at(n - 1).digitValue();
        if (value == -1) return false;
        if ((size - n) % 2 == 0) {
            value *= 2;
            if(value > 9) value -= 9;
        }
        sum += value;
    }
    return (sum + xCheck) % 10 == 0;
}

 

    原文作者:银行家问题
    原文地址: https://blog.csdn.net/qq_27385759/article/details/88667204
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞