天天看点

判断身份证 银行卡 手机号等

//判断手机号
+ (BOOL)checkPhone:(NSString *)phoneNumber{

    if (phoneNumber.length != 11)
    {
        return NO;
    }
    /**
     * 手机号码:
     * 13[0-9], 14[5,7], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[6, 7, 8], 18[0-9], 170[0-9]
     * 移动号段: 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
     * 联通号段: 130,131,132,155,156,185,186,145,176,1709
     * 电信号段: 133,153,180,181,189,177,1700
     */
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[0678])\\d{8}$";
    /**
     * 中国移动:China Mobile
     * 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
     */
    NSString *CM = @"(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)";
    /**
     * 中国联通:China Unicom
     * 130,131,132,155,156,185,186,145,176,1709
     */
    NSString *CU = @"(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)";
    /**
     * 中国电信:China Telecom
     * 133,153,180,181,189,177,1700
     */
    NSString *CT = @"(^1(33|53|77|8[019])\\d{8}$)|(^1700\\d{7}$)";
    /**
     25     * 大陆地区固话及小灵通
     26     * 区号:010,020,021,022,023,024,025,027,028,029
     27     * 号码:七位或八位
     28     */
    //  NSString * PHS = @"^(0[0-9]{2})\\d{8}$|^(0[0-9]{3}(\\d{7,8}))$";
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    if (([regextestmobile evaluateWithObject:phoneNumber] == YES)
        || ([regextestcm evaluateWithObject:phoneNumber] == YES)
        || ([regextestct evaluateWithObject:phoneNumber] == YES)
        || ([regextestcu evaluateWithObject:phoneNumber] == YES))
    {
        return YES;
    }
            return NO;
    

}

#pragma mark - 算法相关
// //精确的身份证号码有效性检测
+ (BOOL)accurateVerifyIDCardNumber:(NSString *)identityString
{
    if (identityString.length != 18) return NO;
    // 正则表达式判断基本 身份证号是否满足格式
    NSString *regex = @"^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$";
    //  NSString *regex = @"^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";
    NSPredicate *identityStringPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    //如果通过该验证,说明身份证格式正确,但准确性还需计算
    if(![identityStringPredicate evaluateWithObject:identityString]) return NO;
    
    //** 开始进行校验 *//
    
    //将前17位加权因子保存在数组里
    NSArray *idCardWiArray = @[@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2"];
    
    //这是除以11后,可能产生的11位余数、验证码,也保存成数组
    NSArray *idCardYArray = @[@"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
    
    //用来保存前17位各自乖以加权因子后的总和
    NSInteger idCardWiSum = 0;
    for(int i = 0;i < 17;i++) {
        NSInteger subStrIndex = [[identityString substringWithRange:NSMakeRange(i, 1)] integerValue];
        NSInteger idCardWiIndex = [[idCardWiArray objectAtIndex:i] integerValue];
        idCardWiSum+= subStrIndex * idCardWiIndex;
    }
    
    //计算出校验码所在数组的位置
    NSInteger idCardMod=idCardWiSum%11;
    //得到最后一位身份证号码
    NSString *idCardLast= [identityString substringWithRange:NSMakeRange(17, 1)];
    //如果等于2,则说明校验码是10,身份证号码最后一位应该是X
    if(idCardMod==2) {
        if(![idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"]) {
            return NO;
        }
    }
    else{
        //用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
        if(![idCardLast isEqualToString: [idCardYArray objectAtIndex:idCardMod]]) {
            return NO;
        }
    }
    return YES;
}
#pragma Mark 银行卡验证有效性
 /** 银行卡号有效性问题Luhn算法
     254  *  现行 16 位银联卡现行卡号开头 6 位是 622126~622925 之间的,7 到 15 位是银行自定义的,
     255  *  可能是发卡分行,发卡网点,发卡序号,第 16 位是校验码。
     256  *  16 位卡号校验位采用 Luhm 校验方法计算:
     257  *  1,将未带校验位的 15 位卡号从右依次编号 1 到 15,位于奇数位号上的数字乘以 2
     258  *  2,将奇位乘积的个十位全部相加,再加上所有偶数位上的数字
     259  *  3,将加法和加上校验位能被 10 整除。
     260  */
+ (BOOL)bankCardluhmCheck:(NSString * )bankCadNumber{
        NSString * lastNum = [[bankCadNumber substringFromIndex:(bankCadNumber.length-1)] copy];//取出最后一位
         NSString * forwardNum = [[bankCadNumber substringToIndex:(bankCadNumber.length -1)] copy];//前15或18位
    
         NSMutableArray * forwardArr = [[NSMutableArray alloc] initWithCapacity:0];
         for (int i=0; i<forwardNum.length; i++) {
                 NSString * subStr = [forwardNum substringWithRange:NSMakeRange(i, 1)];
                 [forwardArr addObject:subStr];
             }
    
         NSMutableArray * forwardDescArr = [[NSMutableArray alloc] initWithCapacity:0];
         for (int i = (int)(forwardArr.count-1); i> -1; i--) {//前15位或者前18位倒序存进数组
                 [forwardDescArr addObject:forwardArr[i]];
             }
    
         NSMutableArray * arrOddNum = [[NSMutableArray alloc] initWithCapacity:0];//奇数位*2的积 < 9
         NSMutableArray * arrOddNum2 = [[NSMutableArray alloc] initWithCapacity:0];//奇数位*2的积 > 9
         NSMutableArray * arrEvenNum = [[NSMutableArray alloc] initWithCapacity:0];//偶数位数组
     
         for (int i=0; i< forwardDescArr.count; i++) {
                 NSInteger num = [forwardDescArr[i] intValue];
                 if (i%2) {//偶数位
                         [arrEvenNum addObject:[NSNumber numberWithInteger:num]];
                     }else{//奇数位
                             if (num * 2 < 9) {
                                     [arrOddNum addObject:[NSNumber numberWithInteger:num * 2]];
                                 }else{
                                         NSInteger decadeNum = (num * 2) / 10;
                                         NSInteger unitNum = (num * 2) % 10;
                                         [arrOddNum2 addObject:[NSNumber numberWithInteger:unitNum]];
                                         [arrOddNum2 addObject:[NSNumber numberWithInteger: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 = [lastNum integerValue];
     
         NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
     
         return (luhmTotal%10 ==0)?YES:NO;
     }