IOS银行卡校验规则(Luhn算法)

原创 2016年08月28日 18:42:03

一、基础知识

银行卡校验规则(Luhn算法)

Luhn检验数字算法 (Luhn Check Digit Algorithm),也叫做模数10公式,是一种简单的算法,用于验证银行卡、信用卡号码的有效性的算法。对所有大型信用卡公司发行的信用卡都起作用, 这些公司包括美国Express、护照、万事达卡、Discover和用餐者俱乐部等。这种算法最初是在20世纪60年代由一组数学家制定,现在Luhn 检验数字算法属于大众,任何人都可以使用它。

算法原理:将每个奇数加倍和使它变为单个的数字,如果必要的话通过减去9和在每个偶数上加上这些值。如果此卡要有效,那么,结果必须是10的倍数。

比如上图的卡号为3759 8765 4321 001 (15位),从最高位开始所有的奇数位相加,偶数为乘以2相加(偶数乘以2后如果大于10则两位数相加),把这些奇数和偶数都加在一起得到57.
(57+3)%10 ==0 如果此卡满足被10整除,则有效位必定为3。
针对目前提现成功(clear_success)的记录里面,统计卡号的位数和数量关系如下:
卡号位数数量
 
<13        3038+
14           538
15           476
16           10884
17           68
18           4395
19          38070
>20        504+
 
说明:
位数少于14的卡号基本是外资银行,或小银行。
***496748***        **     HSBC                               HSBCHKHHHKH  
***430259***        **     HSBC                               HSBCHKHHHKH  
***51878018***     **    Bank of East Asia Limited      BEASHKHHXXX   
位数多于23的卡号大多是卡号包含字母或空格。
62270014 **** 0045 ***      CHINA CONSTRUCTION BANK **                
601382700 **** 9077 **      BANK OF CHINA FOSHAN BRANCH **
 
如果是国内的主流银行(中、农、工、建、招、交等)基本都是基于16位或者19位的卡号。
 
来看看提现成功(clear_success)里面的卡有多少满足Luhn规则
针对16位美元个人用户  准确率:99.84%
正确的卡号数量:3105    不正确的卡号数量 :14
卡号45806509689007** is NOT valid
卡号48620375555016** is NOT valid
卡号54202100231152** is NOT valid
卡号58890201075786** is NOT valid
卡号62106200000456** is NOT valid
卡号62129986037235** is NOT valid
卡号62252017026526** is NOT valid
.....
 
针对19位美元个人用户   准确率:99.96%
正确的卡号数量:10574       不正确的卡号数量 :13  其中3笔发生退票
卡号60138214000567721** is NOT valid
卡号60138217000662109** is NOT valid
卡号60138220005824282** is NOT valid
卡号60138220006014219** is NOT valid
卡号60220001386050410** is NOT valid
卡号62161132000004484** is NOT valid
卡号62220212082154900** is NOT valid
卡号62220836020035821** is NOT valid
卡号63214140980000000** is NOT valid
 
以上都是提现成功的卡号,可以看到基本都严格满足Luhn算法。
卡号位数数量
15      1
16      149
17      4
18      64
19      502
20      3
正确的卡号数量:622

不正确的卡号数量:29 + 1 +4+64+3
14%卡填写违法了Luhn算法,也就是这部分卡号都是可以提前通过Luhn校验发现的。
结论是我们可以在填写收款账户的时候,添加一种Luth算法的JS脚本检查用户填写的卡号存在问题。当然即时用户填写的卡号违法了该规则,我们仍然运行用户填写,但给出相应的警示内容(可能填错)。
 
目前在收银台页面(Checkout.vm)针对信用卡的交易,校验的JS :isValidCardfunction函数就包含了Luth校验规则,必须严格按照该规则的卡才能提交表单。


二、iOS判断银行账号

方法一:

- (BOOL) checkCardNo:(NSString*) cardNo{ 
    int oddsum = 0;     //奇数求和 
    int evensum = 0;    //偶数求和 
    int allsum = 0; 
    int cardNoLength = (int)[cardNo length]; 
    int lastNum = [[cardNo substringFromIndex:cardNoLength-1] intValue]; 
     
    cardNo = [cardNo substringToIndex:cardNoLength - 1]; 
    for (int i = cardNoLength -1 ; i>=1;i--) { 
        NSString *tmpString = [cardNo substringWithRange:NSMakeRange(i-1, 1)]; 
        int tmpVal = [tmpString intValue]; 
        if (cardNoLength % 2 ==1 ) { 
            if((i % 2) == 0){ 
                tmpVal *= 2; 
                if(tmpVal>=10) 
                    tmpVal -= 9; 
                evensum += tmpVal; 
            }else{ 
                oddsum += tmpVal; 
            } 
        }else{ 
            if((i % 2) == 1){ 
                tmpVal *= 2; 
                if(tmpVal>=10) 
                    tmpVal -= 9; 
                evensum += tmpVal; 
            }else{ 
                oddsum += tmpVal; 
            } 
        } 
    } 
     
    allsum = oddsum + evensum; 
    allsum += lastNum; 
    if((allsum % 10) == 0) 
        return YES; 
    else 
        return NO; 

方法二

@interface NSString (Luhm)

- (BOOL)luhmCheck;

@end


@implementation NSString (Luhm)


- (BOOL)luhmCheck{

    NSString * lastNum = [[selfsubstringFromIndex:(self.length-1)]copy];//取出最后一位

    NSString * forwardNum = [[selfsubstringToIndex:(self.length -1)]copy];//1518

    

    NSMutableArray * forwardArr = [[NSMutableArrayalloc] initWithCapacity:0];

    for (int i=0; i<forwardNum.length; i++) {

        NSString * subStr = [forwardNumsubstringWithRange:NSMakeRange(i,1)];

        [forwardArr addObject:subStr];

    }

    

    NSMutableArray * forwardDescArr = [[NSMutableArrayalloc] initWithCapacity:0];

    for (int i =(forwardArr.count-1); i> -1; i--) {//15位或者前18位倒序存进数组

        [forwardDescArr addObject:forwardArr[i]];

    }

    

    NSMutableArray * arrOddNum = [[NSMutableArrayalloc] initWithCapacity:0];//奇数位*2的积 < 9

    NSMutableArray * arrOddNum2 = [[NSMutableArrayalloc] initWithCapacity:0];//奇数位*2的积 > 9

    NSMutableArray * arrEvenNum = [[NSMutableArrayalloc] initWithCapacity:0];//偶数位数组

    

    for (int i=0; i< forwardDescArr.count; i++) {

        NSInteger num = [forwardDescArr[i]intValue];

        if (i%2) {//偶数位

            [arrEvenNum addObject:[NSNumber numberWithInt:num]];

        }else{//奇数位

            if (num *2 < 9) {

                [arrOddNum addObject:[NSNumber numberWithInt:num *2]];

            }else{

                NSInteger decadeNum = (num *2) / 10;

                NSInteger unitNum = (num *2) % 10;

                [arrOddNum2 addObject:[NSNumber numberWithInt:unitNum]];

                [arrOddNum2 addObject:[NSNumber numberWithInt:decadeNum]];

            }

        }

    }

    

    __block  NSInteger sumOddNumTotal = 0;

    [arrOddNum enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {

        sumOddNumTotal += [obj integerValue];

    }];

    

    __block NSInteger sumOddNum2Total = 0;

    [arrOddNum2 enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {

        sumOddNum2Total += [obj integerValue];

    }];

    

    __block NSInteger sumEvenNumTotal =0 ;

    [arrEvenNum enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {

        sumEvenNumTotal += [obj integerValue];

    }];

    

    NSInteger lastNumber = [lastNumintegerValue];

    

    NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;

    

    return (luhmTotal%10 ==0)?YES:NO;

}


@end


参考链接

1.http://blog.csdn.net/lixianyue1991/article/details/44938309

2.http://blog.csdn.net/hmxiao_1983/article/details/29845911

相关文章推荐

iOS 银行卡号合法性判断

输入银行卡号的时候,一般为了卡号的合法性会做一个判断,百度一下查到了Luhn算法 Luhn算法步骤: 1、从卡号的末位开始,逆向将奇数位相加; 2、从卡号的末位开始,逆向将偶数位先乘2,如果得到...

判断银行账号是否输入正确

不多说 直接贴代码 随便输入银行卡号就可以进行判断- (void)viewDidLoad { [super viewDidLoad]; NSString *str = @"622...

银行卡校验规则(Luhn算法)

银行卡校验规则(Luhn算法)   2012-07-09 23:24:17|  分类: 默认分类|举报|字号 订阅        下载LOFTER我...

iOS开发之银行卡校验规则(Luhn算法)

最近的项目中涉及到支付系统

iOS开发银行卡真伪校验

一直想找一个比较完善的银行卡校验,公司的项目要求做校验,跟银行谈了谈 太坑了要收费,然后就自己找了个简单修改下,希望对大家能有帮助!...

iOS中使用Luhn算法验证银行卡

// 银行卡校验 //通过Luhn算法来验证通过 //1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。 //2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,...

AFNetworking3.0版本之前和之后的一些变化

由于苹果在iOS 7.0开始推出NSURLSession网络框架(在iOS 9.0开始NSURLConnection过期)所以AFNetworking从3.0版本开始取消了NSURLConnectio...

Golang MySQL存储过程的使用

Golang MySQL存储过程的使用使用前阅读ref-1:问题来源 [支付系统数据库设计的关键问题 ] ref-2:[Golang 用go-sql-driver 调用MySQL存储过程时的问题...

银行卡校验规则(Luhn算法)

案例: 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过。 该校验的过程: 1、从卡号最后...
  • ywt_go
  • ywt_go
  • 2012年07月09日 19:20
  • 32279

iOS开发 银行卡号有效性问题Luhn算法

/** 银行卡号有效性问题Luhn算法 * 现行 16 位银联卡现行卡号开头 6 位是 622126~622925 之间的,7 到 15 位是银行自定义的, * 可能是发卡分行,发卡网点,发卡...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS银行卡校验规则(Luhn算法)
举报原因:
原因补充:

(最多只允许输入30个字)