IOS 身份证校验详细介绍及示例代码
发布时间 - 2026-01-10 22:20:46 点击率:次IOS 身份证校验

身份证基础知识:
身份证是国民的身份编号,编号是有一定规律的,这里介绍身份证验证规则比较详细。项目中经常会需要对身份证进行校验,我们先了解一些基本知识,然后分析代码
居民身份证号码,根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 居民身份证是国家法定的证明公民个人身份的有效证件。
结构和形式
1.号码的结构
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2.地址码
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3.出生日期码
表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4.顺序码
表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5.校验码
根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码。
地址码
华北地区: 北京市|110000,天津市|120000,河北省|130000,山西省|140000,内蒙古自治区|150000,
东北地区: 辽宁省|210000,吉林省|220000,黑龙江省|230000,
华东地区: 上海市|310000,江苏省|320000,浙江省|330000,安徽省|340000,福建省|350000,江西省|360000,山东省|370000,
华中地区: 河南省|410000,湖北省|420000,湖南省|430000,
华南地区: 广东省|440000,广西壮族自治区|450000,海南省|460000,
西南地区: 重庆市|500000,四川省|510000,贵州省|520000,云南省|530000,西藏自治区|540000,
西北地区: 陕西省|610000,甘肃省|620000,青海省|630000,宁夏回族自治区|640000,新疆维吾尔自治区|650000,
特别地区:台湾地区(886)|710000,香港特别行政区(852)|810000,*特别行政区(853)|820000
中国大陆居民身份证号码中的地址码的数字编码规则为:
第一、二位表示省(自治区、直辖市、特别行政区)。
第三、四位表示市(地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码)。其中,01-20,51-70表示省直辖市;21-50表示地区(自治州、盟)。
第五、六位表示县(市辖区、县级市、旗)。01-18表示市辖区或地区(自治州、盟)辖县级市;21-80表示县(旗);81-99表示省直辖县级市。
生日期码
(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。
顺序码
(身份证号码第十五位到十七位)地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性
校验码
作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且中国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
身份证校验码的计算方法
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2、将这17位数字和系数相乘的结果相加。
3、用加出来和除以11,看余数是多少?
4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X...)
5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字x。
例如:某男性的身份证号码为【53010219200508011x】,我们看看这个身份证是不是合法的身份证。
首先我们得出前17位的乘积和【(5*7)+(3*9)+(0*10)+(1*5)+(0*8)+(2*4)+(1*2)+(9*1)+(2*6)+(0*3)+(0*7)+(5*9)+(0*10)+(8*5)+(0*8)+(1*4)+(1*2)】是189,然后用189除以11得出的结果是189/11=17----2,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。
有了上面的基础知识点,下面具体看一下实现代码
18位身份证验证
-(BOOL)checkUserIDCard:(NSString *)userID
{
//长度不为18的都排除掉
if (userID.length!=18) {
return NO;
}
//校验格式
NSString *regex2 = @"^(^[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 *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
BOOL flag = [identityCardPredicate evaluateWithObject:userID];
if (!flag) {
return flag; //格式错误
}else {
//格式正确在判断是否合法
//将前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 = [[userID substringWithRange:NSMakeRange(i, 1)] integerValue];
NSInteger idCardWiIndex = [[idCardWiArray objectAtIndex:i] integerValue];
idCardWiSum+= subStrIndex * idCardWiIndex;
}
//计算出校验码所在数组的位置
NSInteger idCardMod=idCardWiSum%11;
//得到最后一位身份证号码
NSString * idCardLast= [userID substringWithRange:NSMakeRange(17, 1)];
//如果等于2,则说明校验码是10,身份证号码最后一位应该是X
if(idCardMod==2){
if([idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"]){
return YES;
}else{
return NO;
}
}else{
//用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
if([idCardLast isEqualToString: [idCardYArray objectAtIndex:idCardMod]]){
return YES;
}else{
return NO;
}
}
}
}
15位和18位身份证验证
//正则匹配用户身份证号15或18位
-(BOOL)validateIDCardNumber:(NSString *)value {
value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSInteger length =0;
if (!value) {
return NO;
}else {
length = value.length;
//不满足15位和18位,即身份证错误
if (length !=15 && length !=18) {
return NO;
}
}
// 省份代码
NSArray *areasArray = @[@"11",@"12", @"13",@"14", @"15",@"21", @"22",@"23", @"31",@"32", @"33",@"34", @"35",@"36", @"37",@"41", @"42",@"43", @"44",@"45", @"46",@"50", @"51",@"52", @"53",@"54", @"61",@"62", @"63",@"64", @"65",@"71", @"81",@"82", @"91"];
// 检测省份身份行政区代码
NSString *valueStart2 = [value substringToIndex:2];
BOOL areaFlag =NO; //标识省份代码是否正确
for (NSString *areaCode in areasArray) {
if ([areaCode isEqualToString:valueStart2]) {
areaFlag =YES;
break;
}
}
if (!areaFlag) {
return NO;
}
NSRegularExpression *regularExpression;
NSUInteger numberofMatch;
int year =0;
//分为15位、18位身份证进行校验
switch (length) {
case 15:
//获取年份对应的数字
year = [value substringWithRange:NSMakeRange(6,2)].intValue +1900;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
//创建正则表达式 NSRegularExpressionCaseInsensitive:不区分字母大小写的模式
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$"
options:NSRegularExpressionCaseInsensitive error:nil];//测试出生日期的合法性
}else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$"
options:NSRegularExpressionCaseInsensitive error:nil];//测试出生日期的合法性
}
//使用正则表达式匹配字符串 NSMatchingReportProgress:找到最长的匹配字符串后调用block回调
numberofMatch = [regularExpression numberOfMatchesInString:value
options:NSMatchingReportProgress
range:NSMakeRange(0, value.length)];
if(numberofMatch >0) {
return YES;
}else {
return NO;
}
case 18:
year = [value substringWithRange:NSMakeRange(6,4)].intValue;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$" options:NSRegularExpressionCaseInsensitive error:nil];//测试出生日期的合法性
}else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$" options:NSRegularExpressionCaseInsensitive error:nil];//测试出生日期的合法性
}
numberofMatch = [regularExpression numberOfMatchesInString:value
options:NSMatchingReportProgress
range:NSMakeRange(0, value.length)];
if(numberofMatch >0) {
//1:校验码的计算方法 身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。将这17位数字和系数相乘的结果相加。
int S = [value substringWithRange:NSMakeRange(0,1)].intValue*7 + [value substringWithRange:NSMakeRange(10,1)].intValue *7 + [value substringWithRange:NSMakeRange(1,1)].intValue*9 + [value substringWithRange:NSMakeRange(11,1)].intValue *9 + [value substringWithRange:NSMakeRange(2,1)].intValue*10 + [value substringWithRange:NSMakeRange(12,1)].intValue *10 + [value substringWithRange:NSMakeRange(3,1)].intValue*5 + [value substringWithRange:NSMakeRange(13,1)].intValue *5 + [value substringWithRange:NSMakeRange(4,1)].intValue*8 + [value substringWithRange:NSMakeRange(14,1)].intValue *8 + [value substringWithRange:NSMakeRange(5,1)].intValue*4 + [value substringWithRange:NSMakeRange(15,1)].intValue *4 + [value substringWithRange:NSMakeRange(6,1)].intValue*2 + [value substringWithRange:NSMakeRange(16,1)].intValue *2 + [value substringWithRange:NSMakeRange(7,1)].intValue *1 + [value substringWithRange:NSMakeRange(8,1)].intValue *6 + [value substringWithRange:NSMakeRange(9,1)].intValue *3;
//2:用加出来和除以11,看余数是多少?余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字
int Y = S %11;
NSString *M =@"F";
NSString *JYM =@"10X98765432";
M = [JYM substringWithRange:NSMakeRange(Y,1)];// 3:获取校验位
//4:检测ID的校验位
if ([M isEqualToString:[value substringWithRange:NSMakeRange(17,1)]]) {
return YES;
}else {
return NO;
}
}else {
return NO;
}
default:
return NO;
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# IOS
# 身份证校验
# 身份证校验详解
# 身份证校验实例
# iOS 中使用正则表达式判断身份证格式及银行卡号格式是否正确(推荐)
# IOS开发之由身份证号码提取性别的实现代码
# iOS身份证号码识别示例
# iOS正则表达式验证手机号、邮箱、身份证号等
# IOS身份证识别(OCR源码)详解及实例代码
# iOS判断身份证号码是否正确的方法
# iOS Touch ID 身份认证
# Objective-C实现身份证验证的方法示例
# 身份证号码
# 校验码
# 出生日期
# 县级市
# 七位
# 四位
# 六位
# 能有
# 分别为
# 华中地区
# 验证码
# 和县
# 宁夏回族自治区
# 香港特别行政区
# 西藏自治区
# 西北地区
# 新疆维吾尔自治区
# 西南地区
# 华北地区
# 华南地区
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
,怎么在广州志愿者网站注册?
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
SQL查询语句优化的实用方法总结
Linux安全能力提升路径_长期防护思维说明【指导】
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
如何快速配置高效服务器建站软件?
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
如何解决hover在ie6中的兼容性问题
再谈Python中的字符串与字符编码(推荐)
高性能网站服务器配置指南:安全稳定与高效建站核心方案
如何在阿里云高效完成企业建站全流程?
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
如何在香港免费服务器上快速搭建网站?
如何在建站主机中优化服务器配置?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
如何用狗爹虚拟主机快速搭建网站?
高端云建站费用究竟需要多少预算?
Bootstrap CSS布局之列表
Python并发异常传播_错误处理解析【教程】
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
如何获取免费开源的自助建站系统源码?
Laravel如何使用Telescope进行调试?(安装和使用教程)
JavaScript如何实现路由_前端路由原理是什么
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
javascript日期怎么处理_如何格式化输出
微信小程序 canvas开发实例及注意事项
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
Laravel如何使用Sanctum进行API认证?(SPA实战)
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何快速搭建虚拟主机网站?新手必看指南
Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】
如何在自有机房高效搭建专业网站?
新三国志曹操传主线渭水交兵攻略
javascript如何操作浏览器历史记录_怎样实现无刷新导航
利用python获取某年中每个月的第一天和最后一天
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
如何快速登录WAP自助建站平台?
Python数据仓库与ETL构建实战_Airflow调度流程详解
南京网站制作费用,南京远驱官方网站?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
iOS发送验证码倒计时应用

