PHP实现中国公民身份证号码有效性验证示例代码
本文将使用Java实现中国公民(15位或者18位)身份证号码的相关验证,功能如下:
- 身份证号有效性验证
- 分析详细身份证信息
- 生成一个虚拟的省份证号码。
身份证号码验证
1、号码的结构公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码(前六位数)
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3、出生日期码(第七位至十四位)
表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4、顺序码(第十五位至十七位)
表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5、校验码(第十八位数)
(1)十七位数字本体码加权求和公式S=Sum(Ai*Wi),i=0,…,16,先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子Wi:7910584216379105842
(2)计算模Y=mod(S,11)
(3)通过模得到对应的校验码Y:012345678910校验码:10X98765432
IDValidator.php
checkArg($id); if($code===false){ returnfalse; } //查询cache if(isset(self::$cache[$id])&&self::$cache[$id]['valid']!==false){ returnself::$cache[$id]['valid']; }else{ if(!isset(self::$cache[$id])){ self::$cache[$id]=array(); } } $addr=substr($code['body'],0,6); $birth=$code['type']===18?substr($code['body'],6,8): substr($code['body'],6,6); $order=substr($code['body'],-3); if(!(self::$util->checkAddr($addr)&&self::$util->checkBirth($birth)&& self::$util->checkOrder($order))){ self::$cache[$id]['valid']=false; returnfalse; } //15位不含校验码,到此已结束 if($code['type']===15){ self::$cache[$id]['valid']=true; returntrue; } /*校验位部分*/ //位置加权 $posWeight=array(); for($i=18;$i>1;$i--){ $wei=self::$util->weight($i); $posWeight[$i]=$wei; } //累加body部分与位置加权的积 $bodySum=0; $bodyArr=str_split($code['body']); for($j=0;$j10){ $checkBit=$checkBit%11; } //检查校验码 if($checkBit!=$code['checkBit']){ self::$cache[$id]['valid']=false; returnfalse; }else{ self::$cache[$id]['valid']=true; returntrue; } } //分析详细信息 functiongetInfo($id){ //号码必须有效 if($this->isValid($id)===false){ returnfalse; } //TODO复用此部分 $code=self::$util->checkArg($id); //查询cache //到此时通过isValid已经有了cache记录 if(isset(self::$cache[$id])&&isset(self::$cache[$id]['info'])){ returnself::$cache[$id]['info']; } $addr=substr($code['body'],0,6); $birth=($code['type']===18?substr($code['body'],6,8): substr($code['body'],6,6)); $order=substr($code['body'],-3); $info=array(); $info['addrCode']=$addr; if(self::$GB2260!==null){ $info['addr']=self::$util->getAddrInfo($addr); } $info['birth']=($code['type']===18?(substr($birth,0,4).'-'.substr($birth,4,2).'-'.substr($birth,-2)):('19'.substr($birth,0,2).'-'.substr($birth,2,2).'-'.substr($birth,-2))); $info['sex']=($order%2===0?0:1); $info['length']=$code['type']; if($code['type']===18){ $info['checkBit']=$code['checkBit']; } //记录cache self::$cache[$id]['info']=$info; return$info; } //仿造一个号 functionmakeID($isFifteen=false){ //地址码 $addr=null; if(self::$GB2260!==null){ $loopCnt=0; while($addr===null){ //防止死循环 if($loopCnt>50){ $addr=110101; break; } $prov=self::$util->str_pad(self::$util->rand(66),2,'0'); $city=self::$util->str_pad(self::$util->rand(20),2,'0'); $area=self::$util->str_pad(self::$util->rand(20),2,'0'); $addrTest=$prov.$city.$area; if(isset(self::$GB2260[$addrTest])){ $addr=$addrTest; break; } $loopCnt++; } }else{ $addr=110101; } //出生年 $yr=self::$util->str_pad(self::$util->rand(99,50),2,'0'); $mo=self::$util->str_pad(self::$util->rand(12,1),2,'0'); $da=self::$util->str_pad(self::$util->rand(28,1),2,'0'); if($isFifteen){ return$addr.$yr.$mo.$da .self::$util->str_pad(self::$util->rand(999,1),3,'1'); } $yr='19'.$yr; $body=$addr.$yr.$mo.$da.self::$util->str_pad(self::$util->rand(999,1),3,'1'); //位置加权 $posWeight=array(); for($i=18;$i>1;$i--){ $wei=self::$util->weight($i); $posWeight[$i]=$wei; } //累加body部分与位置加权的积 $bodySum=0; $bodyArr=str_split($body); for($j=0;$j 10){ $checkBit=$checkBit%11; } return($body.$checkBit); } }
调用
makeID(); //获取身份证信息 $info=$v->getInfo($id); var_dump($info); //生成一个15位身份证号 $id=$v->makeID(true); $info=$v->getInfo($id); var_dump($info); //验证身份证号是否正确 var_dump($v->isValid("123456789012345678"));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。