前言
开发过程中,常常需要对一些输入信息进行有效性验证,使用正则表达式进行校验是最简单、效率最高的方式了,下面就来看看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;
}
}