15位和18位身份证JS校验的简单实例


Posted in Javascript onJuly 18, 2016

一、身份证号码的结构和表示形式

1、号码的结构

根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

2、地址码

表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。

3、出生日期码

表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。

4、顺序码

表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。

5、校验码

(1)十七位数字本体码加权求和公式

S = Sum(Ai * Wi), i = 0, ... , 16 ,      先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子
7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

(2)计算模

Y = mod(S, 11)

(3)通过模得到对应的校验码

Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
也就是说,如果得到余数为1则最后的校验位p应该为对应的0。

15位的号码:
a a b b c c y y m m d d x x s
18位的号码:
a a b b c c y y y y m m d d x x s p

二、地址码

身份证前6位为行政区划数字代码(简称数字码)说明(参考《GB/T 2260-2007 中华人民共和国行政区划代码》):该数字码的编制原则和结构分析,它采用三层六位层次码结构,按层次分别表示我国各省(自治区,直辖市,特别行政区)、市(地区,自治州,盟)、县(自治县、县级市、旗、自治旗、市辖区、林区、特区)。

(1)第1、2位数字:所在省份编码,表示省、自治区、直辖市、特别行政区。

省,直辖市代码表: { 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:"国外"} 

(2)第3、4位数字:所在省级市(县)编码,表示市、地区、自治州、盟、直辖市所辖市辖区、县汇总码、省(自治区)直辖县级行政区划汇总码。

——01~20、51~70表示市,直辖市则01表示市区,02以后表示直辖市辖区内的郊县;

——21~50表示地区、自治州、盟;

——90表示省(自治区)直辖县级行政区划汇总码。

(3)第5、6位数字:所在地级县(市)编码,表示县、自治县、县级市、旗、自治旗、市辖区、林区、特区。
——01~20表示市辖区、地区(自治州、盟)辖县级市、市辖特区以及省(自治区)直辖县级行政区划中的县级市,01通常表示辖区汇总码;

——21~80表示县、自治县、旗、自治旗、林区、地区辖特区;

——81~99表示省(自治区)辖县级市。

三、其它

15位身份证号码:

第7、8位为出生年份(两位数,用年份的后两位表示),
第9、10位为出生月份,
第11、12位代表出生日期,
第13、14位为顺序码,这个是随机数,
第15位代表性别,奇数为男,偶数为女。

18位身份证号码:

第7、8、9、10位为出生年份(四位数),
第11、12位为出生月份,
第13、14位代表出生日期,
第15、16位为顺序码,
第17位代表性别,奇数为男,偶数为女。
最后一位为校验位。

四、Js代码实例

var idCardNoUtil = {
 /*省,直辖市代码表*/
 provinceAndCitys: {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:"国外"},

 /*每位加权因子*/
 powers: ["7","9","10","5","8","4","2","1","6","3","7","9","10","5","8","4","2"],
 
 /*第18位校检码*/
 parityBit: ["1","0","X","9","8","7","6","5","4","3","2"],

 /*性别*/
 genders: {male:"男",female:"女"},

 /*校验地址码*/
 checkAddressCode: function(addressCode){
   var check = /^[1-9]\d{5}$/.test(addressCode);
   if(!check) return false;
   if(idCardNoUtil.provinceAndCitys[parseInt(addressCode.substring(0,2))]){
    return true;
   }else{
    return false;
   }
 },

 /*校验日期码*/
 checkBirthDayCode: function(birDayCode){
   var check = /^[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$/.test(birDayCode);
   if(!check) return false;  
   var yyyy = parseInt(birDayCode.substring(0,4),10);
   var mm = parseInt(birDayCode.substring(4,6),10);
   var dd = parseInt(birDayCode.substring(6),10);
  var xdata = new Date(yyyy,mm-1,dd);
  if(xdata > new Date()){
   return false;//生日不能大于当前日期
  }else if ( ( xdata.getFullYear() == yyyy ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == dd ) ){
   return true;
  }else{
   return false;
  }
 },
 
 /*计算校检码*/
 getParityBit: function(idCardNo){
  var id17 = idCardNo.substring(0,17);  
   /*加权 */
   var power = 0;
   for(var i=0;i<17;i++){
    power += parseInt(id17.charAt(i),10) * parseInt(idCardNoUtil.powers[i]);
   }       
   /*取模*/ 
   var mod = power % 11;
   return idCardNoUtil.parityBit[mod];
 },
 
 /*验证校检码*/
 checkParityBit: function(idCardNo){
   var parityBit = idCardNo.charAt(17).toUpperCase();
   if(idCardNoUtil.getParityBit(idCardNo) == parityBit){
     return true;
   }else{
     return false;
   }
 },

 /*校验15位或18位的身份证号码*/
 checkIdCardNo: function(idCardNo){
  //15位和18位身份证号码的基本校验
  var check = /^\d{15}|(\d{17}(\d|x|X))$/.test(idCardNo);
  if(!check) return false;
  //判断长度为15位或18位 
  if(idCardNo.length==15){
    return idCardNoUtil.check15IdCardNo(idCardNo);
  }else if(idCardNo.length==18){
    return idCardNoUtil.check18IdCardNo(idCardNo);
  }else{
    return false;
  }
 },

 //校验15位的身份证号码
 check15IdCardNo: function(idCardNo){
   //15位身份证号码的基本校验
   var check = /^[1-9]\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}$/.test(idCardNo);  
   if(!check) return false;
   //校验地址码
   var addressCode = idCardNo.substring(0,6);
   check = idCardNoUtil.checkAddressCode(addressCode);
   if(!check) return false;
   var birDayCode = '19' + idCardNo.substring(6,12);
   //校验日期码
   return idCardNoUtil.checkBirthDayCode(birDayCode);
 },

 //校验18位的身份证号码
 check18IdCardNo: function(idCardNo){
   //18位身份证号码的基本格式校验
   var check = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}(\d|x|X)$/.test(idCardNo);
   if(!check) return false;
   //校验地址码
   var addressCode = idCardNo.substring(0,6);
   check = idCardNoUtil.checkAddressCode(addressCode);
   if(!check) return false;
   //校验日期码
   var birDayCode = idCardNo.substring(6,14);
   check = idCardNoUtil.checkBirthDayCode(birDayCode);
   if(!check) return false;
   //验证校检码  
   return idCardNoUtil.checkParityBit(idCardNo);  
 },

 formateDateCN: function(day){
    var yyyy =day.substring(0,4);
    var mm = day.substring(4,6);
    var dd = day.substring(6);
    return yyyy + '-' + mm +'-' + dd;
 },

 //获取信息
 getIdCardInfo: function(idCardNo){
   var idCardInfo = {
    gender:"",  //性别
    birthday:"" // 出生日期(yyyy-mm-dd)
   };
  if(idCardNo.length==15){
    var aday = '19' + idCardNo.substring(6,12);
    idCardInfo.birthday=idCardNoUtil.formateDateCN(aday);
    if(parseInt(idCardNo.charAt(14))%2==0){
      idCardInfo.gender=idCardNoUtil.genders.female;
    }else{
      idCardInfo.gender=idCardNoUtil.genders.male;
    }   
  }else if(idCardNo.length==18){
    var aday = idCardNo.substring(6,14);
    idCardInfo.birthday=idCardNoUtil.formateDateCN(aday);
     if(parseInt(idCardNo.charAt(16))%2==0){
      idCardInfo.gender=idCardNoUtil.genders.female;
    }else{
      idCardInfo.gender=idCardNoUtil.genders.male;
    } 
    
  }
  return idCardInfo;
 },
 
 /*18位转15位*/
 getId15: function(idCardNo){
  if(idCardNo.length==15){
    return idCardNo;
  }else if(idCardNo.length==18){
    return idCardNo.substring(0,6) + idCardNo.substring(8,17); 
  }else{
  return null;
  }
 },
 
 /*15位转18位*/
 getId18: function(idCardNo){
  if(idCardNo.length==15){
    var id17 = idCardNo.substring(0,6) + '19' + idCardNo.substring(6);
    var parityBit = idCardNoUtil.getParityBit(id17);
    return id17 + parityBit;
  }else if(idCardNo.length==18){
    return idCardNo;
  }else{
  return null;
  }
 }
};

//身份证号码验证  
jQuery.validator.addMethod("idCardNo", function(value, element) { 
  return this.optional(element) || idCardNoUtil.checkIdCardNo(value); 
}, "Please specify a valid ID number."); 

//获取身份证信息 
var idCardInfo = idCardNoUtil.getIdCardInfo(idCardNo); 
alert(idCardInfo.gender + "|" + idCardInfo.birthday); 

注:录入并判断数据库中是否已存在同样的身份证时 
(1) 若输入的是15位的身份证:先查找15位的ID是否存在,若不存在还需要将15位的身份证转成18位的身份证,仍不存在的话才可录入系统。 
(2) 若输入的是18位的身份证:先查找18位的ID是否存在,若不存在还需要将18位的身份证转成15位的身份证,仍不存在的话才可录入系统。 
如果找到对应的15位身份证,需要将15位的更新到18位。

以上这篇15位和18位身份证JS校验的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
使用jquery实现div的tab切换实例代码
May 27 Javascript
Js放到HTML文件中的哪个位置有什么区别
Aug 21 Javascript
Jquery图片延迟加载插件jquery.lazyload.js的使用方法
May 21 Javascript
jQuery前端开发35个小技巧
May 24 Javascript
下一代Bootstrap的5个特点 超酷炫!
Jun 17 Javascript
PHP实现本地图片上传和验证功能
Feb 27 Javascript
seajs中最常用的7个功能、配置示例
Oct 10 Javascript
vue.js element-ui validate中代码不执行问题解决方法
Dec 18 Javascript
详解vuex结合localstorage动态监听storage的变化
May 03 Javascript
node.js利用socket.io实现多人在线匹配联机五子棋
May 31 Javascript
angularjs实现对表单输入改变的监控(ng-change和watch两种方式)
Aug 29 Javascript
如何在JavaScript中创建具有多个空格的字符串?
Feb 23 Javascript
Bootstrap零基础入门教程(二)
Jul 18 #Javascript
Bootstrap插件全集
Jul 18 #Javascript
全面了解javascript中的错误处理机制
Jul 18 #Javascript
JavaScript中ES6 Babel正确安装过程
Jul 18 #Javascript
深入理解JS正则表达式---分组
Jul 18 #Javascript
基于jQuery实现弹出可关闭遮罩提示框实例代码
Jul 18 #Javascript
简单的JS轮播图代码
Jul 18 #Javascript
You might like
php 接口类与抽象类的实际作用
2009/11/26 PHP
php中session_unset与session_destroy的区别分析
2011/06/16 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
thinkphp学习笔记之多表查询
2014/07/28 PHP
浅谈PHP中JSON数据操作
2015/07/01 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
PHP操作FTP类 (上传、下载、移动、创建等)
2016/03/31 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
php工具型代码之印章抠图
2018/07/18 PHP
javascript 面向对象全新理练之数据的封装
2009/12/03 Javascript
javascript 模式设计之工厂模式学习心得
2010/04/27 Javascript
js给页面加style无效果的解决方法
2014/01/20 Javascript
JavaScript表单通过正则表达式验证电话号码
2014/03/14 Javascript
浅谈javascript的Touch事件
2015/09/27 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
2016/08/04 Javascript
微信小程序tabBar底部导航中文注解api详解
2017/08/16 Javascript
react-native 圆弧拖动进度条实现的示例代码
2018/04/12 Javascript
微信小程序实现上传照片代码实例解析
2020/08/04 Javascript
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
python多任务及返回值的处理方法
2019/01/22 Python
Python 使用list和tuple+条件判断详解
2019/07/30 Python
python3实现的zip格式压缩文件夹操作示例
2019/08/17 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
Python使用py2neo操作图数据库neo4j的方法详解
2020/01/13 Python
Python数据可视化实现多种图例代码详解
2020/07/14 Python
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
浅析HTML5:'data-'属性的作用
2018/01/23 HTML / CSS
C/C++有关内存的思考题
2015/12/04 面试题
爱情寄语大全
2014/04/09 职场文书
祖国在我心中演讲稿400字
2014/05/04 职场文书
捐款倡议书格式范文
2014/05/14 职场文书
孝老爱亲模范事迹材料
2014/05/25 职场文书
小学生迎国庆演讲稿
2014/09/05 职场文书
离婚财产处理协议书
2014/09/30 职场文书
优秀的商业计划书,让融资一步到位
2019/05/07 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书