新公司框架源码的时候,发现了这个功能,于是搜索一番并封装了一下身份证号校验的类。
目前大家的身份证号大多是 18 位的,当然,也不排除有些老人的身份证号是 15 位的。
如果强制要求是 18 位的话,会比较好,因为 15 位的身份证号没有校验码,可以说,只要了解大概结构,随手都可以造出一系列身份证号码来。
当然,如果只是单纯的程序校验, 18 位的身份证号码也可以伪造,就是需要伪造者花点心思。
最好的还是调用相关部门给的接口,进行校验。
本文所编写的身份证号码校验,只是针对相关规则下的计算,是调用接口前能做的事情。
身份证号规则
15位:省份(2位) + 地级市(2位) + 县级市(2位) + 出生年(2位) + 出生月(2位) + 出生日(2位) + 顺序号(3位)
18位:省份(2位) + 地级市(2位) + 县级市(2位) + 出生年(4位) + 出生月(2位) + 出生日(2位) + 顺序号(3位) + 校验位(1位)
相比之下, 18位 比 15位 多出生年 2位 、校验位 1位 。
其中,顺序号如果是偶数,则说明是女生,顺序号是奇数,则说明是男生。
校验位的计算:
有17位数字,分别是:
7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
分别用身份证的前 17 位乘以上面相应位置的数字,然后相加。
接着用相加的和对 11 取模。
用获得的值在下面 11 个字符里查找对应位置的字符,这个字符就是校验位。
'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'
15位转18位:
从上述的分析中,可以知道,只要补充上年分和校验位就可以了。
一般情况下年份补充都是加上 19 就可以了。
校验类的实现
通过分析身份证号的规则,了解到,有几点是可以做的:
检查身份是否正确(一般不会变化,而且省份不多) 检查地级市和县级市(如果有这方面的资源,可以考虑,不过一般不建议) 检查年月日 检查校验码当然,因为可能部分人用的是 15位 的身份证号,所以需要一个转换的方法,不过,这里还是建议限制需要 18位 的身份证号。
下面开始实现:
初始化:
class IDCardFilter{ /** * 身份证号码校验 * * @param string $idCard * @return bool */ public function vaild($idCard) { // 基础的校验,校验身份证格式是否正确 if (!$this->isCardNumber($idCard)) { return false; } // 将 15 位转换成 18 位 $idCard = $this->fifteen2Eighteen($idCard); // 检查省是否存在 if (!$this->checkProvince($idCard)) { return false; } // 检查生日是否正确 if (!$this->checkBirthday($idCard)) { return false; } // 检查校验码 return $this->checkCode($idCard); }}
新闻热点
疑难解答