iOS 身份证号验证

前言

开发过程中,常常需要对一些输入信息进行有效性验证,使用正则表达式进行校验是最简单、效率最高的方式了,下面就来看看15/18位身份证号码验证的正则表达式吧。

介绍

居民身份证号

十八位: xxxxxx yyyy MM dd 375 0
十五位: xxxxxx yy MM dd 75 0

地区:[1-9]\d{5}
年的前两位: (18|19|([23]\d)) 1800-2399
年的后两位: \d{2}
月份: ((0[1-9])|(10|11|12))
天数:(([0-2][1-9])|10|20|30|31) 闰年不能禁止29+

三位顺序码:\d{3}
两位顺序码: \d{2}
校验码: [0-9Xx]

/*
 * 身份证15位编码规则:dddddd yymmdd xx p
 * dddddd:6位地区编码
 * yymmdd: 出生年(两位年)月日,如:910215
 * xx: 顺序编码,系统产生,无法确定
 * p: 性别,奇数为男,偶数为女
 * 
 * 身份证18位编码规则:dddddd yyyymmdd xxx y
 * dddddd:6位地区编码
 * yyyymmdd: 出生年(四位年)月日,如:19910215
 * xxx:顺序编码,系统产生,无法确定,奇数为男,偶数为女
 * y: 校验码,该位数值可通过前17位计算获得
 * 
 * 前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
 * 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
 * 如果验证码恰好是10,为了保证身份证是十八位,那么第十八位将用X来代替
 * 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
 * i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
 */

正则表达式


十八位: ^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$

十五位: ^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$

总结:

^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$

上代码


/**
 校验身份证号码是否正确 返回BOOL值

 @param idCardString 身份证号码
 @return 返回BOOL值 YES or NO
 */
+ (BOOL)cly_verifyIDCardString:(NSString *)idCardString {
    NSString *regex = @"^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    BOOL isRe = [predicate evaluateWithObject:idCardString];
    if (!isRe) {
         //身份证号码格式不对
        return NO;
    }
    //加权因子 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
    NSArray *weightingArray = @[@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2"];
    //校验码 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2
    NSArray *verificationArray = @[@"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
    
    NSInteger sum = 0;//保存前17位各自乖以加权因子后的总和
    for (int i = 0; i < weightingArray.count; i++) {//将前17位数字和加权因子相乘的结果相加
        NSString *subStr = [idCardString substringWithRange:NSMakeRange(i, 1)];
        sum += [subStr integerValue] * [weightingArray[i] integerValue];
    }
    
    NSInteger modNum = sum % 11;//总和除以11取余
    NSString *idCardMod = verificationArray[modNum]; //根据余数取出校验码
    NSString *idCardLast = [idCardString.uppercaseString substringFromIndex:17]; //获取身份证最后一位
    
    if (modNum == 2) {//等于2时 idCardMod为10  身份证最后一位用X表示10
        idCardMod = @"X";
    }
    if ([idCardLast isEqualToString:idCardMod]) { //身份证号码验证成功
        return YES;
    } else { //身份证号码验证失败
        return NO;
    }
}

你可能感兴趣的:(iOS 身份证号验证)