这是一个用于验证中国大陆身份证号码有效性的 PHP 函数 check_id_card($idCard),主要通过三层校验确保身份证号码符合规范,具体介绍如下:
该函数接收一个身份证号码字符串作为参数,通过校验其长度、格式规则和校验码,返回一个布尔值(true 表示有效,false 表示无效),用于判断该号码是否符合中国大陆身份证的编码规范。
- 规则:中国大陆第二代身份证号码固定为 18 位。
- 实现:通过
strlen($idCard) != 18 判断,如果长度不是 18 位,直接返回 false。
- 规则:使用正则表达式验证身份证号码的结构是否符合编码规则,具体包括:
- 第 1-6 位:省级行政区代码(第一位非 0,后 5 位为数字)。
- 第 7-10 位:出生年份(限定为 18xx、19xx、20xx 年)。
- 第 11-12 位:出生月份(01-12 月)。
- 第 13-14 位:出生日期(01-31 日,注:此处仅校验格式,不严格验证月份对应的天数,如 2 月 30 日会通过此步)。
- 第 15-17 位:顺序码(数字,其中第 17 位奇数为男性,偶数为女性)。
- 第 18 位:校验码(数字或大写 / 小写 X)。
- 实现:通过正则表达式
'/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[\dXx]$/' 匹配,不匹配则返回 false。
身份证第 18 位为校验码,由前 17 位计算得出,用于防止号码输入错误,计算逻辑如下:
- 步骤 1:定义权重因子数组
$factor = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2](对应前 17 位的权重)。
- 步骤 2:定义校验码映射表
$verifyCodes = ['1','0','X','9','8','7','6','5','4','3','2'](索引 0-10 对应可能的校验结果)。
- 步骤 3:计算前 17 位数字与对应权重的乘积之和(
$sum)。
- 步骤 4:计算总和除以 11 的余数(
$mod = $sum % 11)。
- 步骤 5:根据余数从映射表中获取理论校验码(
$verifyCode = $verifyCodes[$mod])。
- 步骤 6:将身份证第 18 位转换为大写后,与理论校验码比对,一致则有效。
- 未严格验证出生日期的合理性(如 2 月 30 日、4 月 31 日等无效日期会通过格式校验)。
- 未校验前 6 位行政区划代码的真实性(仅验证格式,不判断是否为真实存在的地区代码)。
- 仅支持 18 位身份证号码(不兼容 15 位旧身份证)。
适用于对身份证号码进行初步格式和校验码验证的场景(如表单提交、用户信息录入时的合法性检查),可快速过滤明显错误的号码,但如需更严格验证(如真实出生日期、真实地区代码),需结合额外逻辑补充。
function check_id_card($idCard) {
// 长度校验
if (strlen($idCard) != 18) {
return false;
}
// 基本格式校验
if (!preg_match('/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[\dXx]$/', $idCard)) {
return false;
}
// 校验码验证
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$verifyCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += $idCard[$i] * $factor[$i];
}
$mod = $sum % 11;
$verifyCode = $verifyCodes[$mod];
return strtoupper($idCard[17]) == $verifyCode;
}
转载:感谢您的认可,转载请说明文章出处。
很赞哦! ({{ infoItems.like }})