Js实现中国公民身份证号码有效性验证实例代码
本文将使用JavaScript实现中国公民(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
此处将使用一个全国的地址码GB2260,在下面的下载地址可以看到。
/* *http://blog.jdk5.com/zh/javascript-chinese-personal-id-card-validation/ */ functionIDValidator(){ varparam={ error:{ longNumber:'长数字存在精度问题,请使用字符串传值!Longnumberisnotallowed,becausetheprecisionoftheNumberInJavaScript.' } }; varutil={ checkArg:function(id){ varargType=(typeofid); switch(argType){ case'number': //longnumbernotallowed id=id.toString(); if(id.length>15){ this.error(param.error.longNumber); returnfalse; } break; case'string': break; default: returnfalse; } id=id.toUpperCase(); varcode=null; if(id.length===18){ //18位 code={ body:id.slice(0,17), checkBit:id.slice(-1), type:18 }; }elseif(id.length===15){ //15位 code={ body:id, type:15 }; }else{ returnfalse; } returncode; } //地址码检查 , checkAddr:function(addr,GB2260){ varaddrInfo=this.getAddrInfo(addr,GB2260); return(addrInfo===false?false:true); } //取得地址码信息 , getAddrInfo:function(addr,GB2260){ GB2260=GB2260||null; //查询GB/T2260,没有引入GB2260时略过 if(GB2260===null){ returnaddr; } if(!GB2260.hasOwnProperty(addr)){ //考虑标准不全的情况,搜索不到时向上搜索 vartmpAddr; tmpAddr=addr.slice(0,4)+'00'; if(!GB2260.hasOwnProperty(tmpAddr)){ tmpAddr=addr.slice(0,2)+'0000'; if(!GB2260.hasOwnProperty(tmpAddr)){ returnfalse; }else{ returnGB2260[tmpAddr]+'未知地区'; } }else{ returnGB2260[tmpAddr]+'未知地区'; } }else{ returnGB2260[addr]; } } //生日码检查 , checkBirth:function(birth){ varyear,month,day; if(birth.length==8){ year=parseInt(birth.slice(0,4),10); month=parseInt(birth.slice(4,6),10); day=parseInt(birth.slice(-2),10); }elseif(birth.length==6){ year=parseInt('19'+birth.slice(0,2),10); month=parseInt(birth.slice(2,4),10); day=parseInt(birth.slice(-2),10); }else{ returnfalse; } //TODO是否需要判断年份 /* *if(year<1800){returnfalse;} */ //TODO按月份检测 if(month>12||month===0||day>31||day===0){ returnfalse; } returntrue; } //顺序码检查 , checkOrder:function(order){ //暂无需检测 returntrue; } //加权 , weight:function(t){ returnMath.pow(2,t-1)%11; } //随机整数 , rand:function(max,min){ min=min||1; returnMath.round(Math.random()*(max-min))+min; } //数字补位 , str_pad:function(str,len,chr,right){ str=str.toString(); len=len||2; chr=chr||'0'; right=right||false; if(str.length>=len){ returnstr; }else{ for(vari=0,j=len-str.length;i1;i--){ varwei=util.weight(i); posWeight[i]=wei; } //累加body部分与位置加权的积 varbodySum=0; varbodyArr=code.body.split(''); for(varj=0;j 10){ checkBit=checkBit%11; } checkBit=(typeofcheckBit==='number'?checkBit.toString() :checkBit); //检查校验码 if(checkBit!==code.checkBit){ this.cache[id].valid=false; returnfalse; }else{ this.cache[id].valid=true; returntrue; } } //分析详细信息 , getInfo:function(id){ varGB2260=this.GB2260||null; //号码必须有效 if(this.isValid(id)===false){ returnfalse; } //TODO复用此部分 varcode=util.checkArg(id); //查询cache //到此时通过isValid已经有了cache记录 if(typeofthis.cache[id].info!=='undefined'){ returnthis.cache[id].info; } varaddr=code.body.slice(0,6); varbirth=(code.type===18?code.body.slice(6,14):code.body .slice(6,12)); varorder=code.body.slice(-3); varinfo={}; info.addrCode=addr; if(GB2260!==null){ info.addr=util.getAddrInfo(addr,GB2260); } info.birth=(code.type===18?(([birth.slice(0,4), birth.slice(4,6),birth.slice(-2)]).join('-')):([ '19'+birth.slice(0,2),birth.slice(2,4), birth.slice(-2)]).join('-')); info.sex=(order%2===0?0:1); info.length=code.type; if(code.type===18){ info.checkBit=code.checkBit; } //记录cache this.cache[id].info=info; returninfo; } //仿造一个号 , makeID:function(isFifteen){ varGB2260=this.GB2260||null; //地址码 varaddr=null; if(GB2260!==null){ varloopCnt=0; while(addr===null){ //防止死循环 if(loopCnt>10){ addr=110101; break; } varprov=util.str_pad(util.rand(50),2,'0'); varcity=util.str_pad(util.rand(20),2,'0'); vararea=util.str_pad(util.rand(20),2,'0'); varaddrTest=[prov,city,area].join(''); if(GB2260[addrTest]){ addr=addrTest; break; } } }else{ addr=110101; } //出生年 varyr=util.str_pad(util.rand(99,50),2,'0'); varmo=util.str_pad(util.rand(12,1),2,'0'); varda=util.str_pad(util.rand(28,1),2,'0'); if(isFifteen){ returnaddr+yr+mo+da +util.str_pad(util.rand(999,1),3,'1'); } yr='19'+yr; varbody=addr+yr+mo+da +util.str_pad(util.rand(999,1),3,'1'); //位置加权 varposWeight=[]; for(vari=18;i>1;i--){ varwei=util.weight(i); posWeight[i]=wei; } //累加body部分与位置加权的积 varbodySum=0; varbodyArr=body.split(''); for(varj=0;j 10){ checkBit=checkBit%11; } checkBit=(typeofcheckBit==='number'?checkBit.toString() :checkBit); return(body+checkBit); } };//_IDValidator GB2260=GB2260==null?"":GB2260; returnnew_IDValidator(GB2260); }
调用如下:
//新建普通实例 varValidator=newIDValidator(); //验证号码是否合法,合法返回true,不合法返回false Validator.isValid(code); //号码合法时返回分析信息(地区、出生日期、性别、校验位),不合法返回false Validator.getInfo(code); //仿造一个18位身份证号 Validator.makeID(); //仿造一个15位身份证号 Validator.makeID(true);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。