`
jaybril
  • 浏览: 51330 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

18位身份证号藏了什么玄机?用js教你校验身份证

阅读更多

大家好,想必各位程序猿已经有所发现,而相应地,在日常的开发任务需求了很多跟涉及到用户的都几乎需要用到身份证的校验,因此不留君特意整理出一份身份证号的组成原理以及

校验函数(js版)

【身份证号码的规则】

6位地方代码+8位出生年月日数字+2位顺序码+1位性别代码+1位校验码

 

1)地方代码:

地方代码的前两位由特定的省份代码组成,至于原理呢...没有,我们并不需要纠结或者记住来源,只需要校验输入身份证号中的前两位是否在这些省份代码里即可

{

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:"国外 "};

 

于是我们可以定义一个省份代码数组,并且编写一个校验前两位的函数:

var checkCityNoIsOk=function (cityNo) {

        var provinceCodeArr = [

         "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"

         ];

        for (var i = 0; i < provinceCodeArr.length; i++) {

            if (cityNo == provinceCodeArr[i]) {

                return true;

            }

        }

        return false;

    }

有了这个函数,地方代码的校验就妥妥的了,网友可能会疑惑,地方代码不是6位吗,为什么只校验前两位就可以了呢?别急,先走下一个环节

 

2)出生年月日

出生年月日没什么玄机的,只要校验出年月日是标准的年月日即可,于是我们可以创建一个函数来校验年月日的,如下

var checkBirthIsOk=function(year,month,day){

try{

    //获取年龄

var age = Math.round( (nowdate - bir) / (365 * 24 * 60 * 60 * 1000));

if(age>=18){

  return true;

}

}

catch(e){

 //一切不标准的年月日都会抛出异常

 return false;

}

return false;

}

代码中有18岁的校验,是因为以前的要求是成年人才有身份证,现在貌似一出生就有身份证号了,如果真是这样,则把18岁的判断限制去掉即可。

 

3)顺序码:

表示在同一省份代码所标识的区域范围内,对同年同月同日出生的人编定的顺序号,顺序码的奇数为男,偶数为女

 

4)校验码:

校验码是根据前面17位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码

算出来的校验码范围为1-10但是如果是10为了遵循18位身份证号的规则,就得用X来替代10,这就解释了为什么

有些身份证号码最后一位是X

校验码的规则是:

1.身份证的前17位,每一位乘以一个相应的加权因子

他们对应的因子为[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]

2.得出新的17位数相加。

3.用加出来和除以11求余数

4.余数对应校验表[1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2],其中10展现为X

5.得到余数对应校验表。比如余数是0则结果1  余数是4结果是9...

于是我们可以创建一个函数来校验:

var checkFactorIsOk=function(idCardNo){

   var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];// 加权因子

       var checktable = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];// 校验值对应表

       var checksum = 0;

       var befor17 = idCardNo.substr(0, 17);

       for (var i = 0; i < 17; i++) {

             var num = parseInt(befor17.substr(i, 1)) * factor[i];

             checksum += num;

            }

        //结果求余

       var yushu = checksum % 11;

       // 余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字

       if (yushu > 10) {

           return false;

         }

       var s = checktable[yushu];

       var checkNoStr = idCardNo.substr(17, 1);

       if (checkNoStr) {

          // 如果是“X”或者“x” 第二位 则只能对应 对应表的 10

          if (checkNoStr == "X" || checkNoStr == "X") {

              if (s == 10) {

                  return true;

                } else {

                  return false;

                  }

                }

                // 如果不是字母,则最后一位分别对应 对应表 即可

           else if (parseInt(checkNoStr) == s) {

                     return true;

                  } else {

                     return false;

                 }

         }                         

}

 

 

最终完整的代码如下:

var checkIdCardIsOk = function (idcardNo) {

    //校验省份代码

    var checkCityNoIsOk = function (cityNo) {

        var provinceCodeArr = [

            "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"

        ];

        for (var i = 0; i < provinceCodeArr.length; i++) {

            if (cityNo == provinceCodeArr[i]) {

                return true;

            }

        }

        return false;

    }

//校验出生日期

    var checkBirthIsOk = function (year, month, day) {

        try {

            //获取年龄

            var nowdate=new Date();

            var bir = new Date(bstr.substring(0, 4), bstr.substring(4, 6), bstr.substring(6, 8));

            var age = Math.round((nowdate - bir) / (365 * 24 * 60 * 60 * 1000));

            if (age >= 18) {

                return true;

            }

        }

        catch (e) {

            //一切不标准的年月日都会抛出异常

            return false;

        }

        return false;

    }

//校验顺序码和校验码

    var checkFactorIsOk = function (idCardNo) {

        var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];// 加权因子

        var checktable = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];// 校验值对应表

        var checksum = 0;

        var befor17 = idCardNo.substr(0, 17);

        for (var i = 0; i < 17; i++) {

            var num = parseInt(befor17.substr(i, 1)) * factor[i];

            checksum += num;

        }

        //结果求余

        var yushu = checksum % 11;

        // 余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字

        if (yushu > 10) {

            return false;

        }

        var s = checktable[yushu];

        var checkNoStr = idCardNo.substr(17, 1);

        if (checkNoStr) {

            // 如果是“X”或者“x” 第二位 则只能对应 对应表的 10

            if (checkNoStr == "X" || checkNoStr == "X") {

                if (s == 10) {

                    return true;

                } else {

                    return false;

                }

            }

            // 如果不是字母,则最后一位分别对应 对应表 即可

            else if (parseInt(checkNoStr) == s) {

                return true;

            } else {

                return false;

            }

        }

    }

    if (!idcardNo) {

        return false;

    }

    idcardNo = idcardNo.toUpperCase();

    //整体校验

    var isMatch = (/^(\d{17})([0-9]|X)$/.test(idcardNo));

    if (!isMatch) {

        return false;

    }

    //省份代码校验

    var city = idcardNo.substr(0, 2);

    if (!checkCityNoIsOk(city)) {

        return false;

    }

    //出生年月日校验

    var bstr = idcardNo.substr(6, 8);

    var year = bstr.substring(0, 4);

    var month = bstr.substring(4, 6);

    var day = bstr.substring(6, 8);

 

    if (!checkBirthIsOk(year, month, day)) {

        return false;

    }

    //校验码+顺序码校验

    if (!checkFactorIsOk(idcardNo)) {

        return false;

    }

    return true;

}

 

使用方法:

var isok=checkIdCardIsOk("45258119860923393X");

console.log(isok);//false

 

到这里本文就基本结束了,至于一开始说的地区代码为何只校验前两位,是因为三四位是市级代码、五六位是县级代码,这些代码数量众多,一一校验会很耗费性能,而在后面的校验码和顺序码的校验会涉及到前面17位,因此只要前面有一位数字是错误的都会导致生成的校验码是错误的,因此校验也不能通过,故而只校验前两位。

 


 

觉得本文对你有帮助?请分享给更多人

关注「编程无界」,提升装逼技能

 

 

0
0
分享到:
评论

相关推荐

    汽车知识之教您看懂汽车玻璃隐藏的玄机.doc

    汽车知识之教您看懂汽车玻璃隐藏的玄机.doc

    行业-A股外资行为分析暨转型牛系列之四-从消费到制造,外资动向有何玄机?.rar

    标题中的“行业-A股外资行为分析暨转型牛系列之四-从消费到制造,外资动向有何玄机?”暗示了这个文档可能是一个深入探讨中国A股市场中外资投资行为的报告,特别是关注外资如何从消费领域转向制造业的投资趋势。这份...

    数据挖掘寻线索 大修工程藏玄机.pdf

    数据挖掘寻线索 大修工程藏玄机.pdf

    20210420-东北证券-A股外资行为分析暨转型牛系列之四:从消费到制造,外资动向有何玄机?.pdf

    在分析这份报告《***-东北证券-A股外资行为分析暨转型牛系列之四:从消费到制造,外资动向有何玄机?》之前,我们需要了解以下知识点: 1. 陆股通的概念:陆股通是指通过沪深股通机制,香港和境外其他地区的投资者...

    移动医疗APP“加号”背后藏玄机或成为号贩子2.0.pdf

    移动医疗APP“加号”背后藏玄机或成为号贩子2.0.pdf

    玄机宝盒3.0版本备份

    这表明玄机宝盒3.0可能集成了对JavaScript的支持,或者使用了ClearScript V8来实现某种脚本自动化或扩展功能。 其次,Msdn5CoreBox.exe是玄机宝盒软件的主执行程序,它的存在意味着用户可以通过这个可执行文件来...

    绿色消防器材藏着哪些玄机.pdf

    绿色消防器材藏着哪些玄机.pdf

    玄机宝盒v1.9.0(C#百宝箱)(C#调试、正则、抓包工具)

    "玄机宝盒v1.9.0(C#百宝箱)”是一个集成了多种功能的C#编程辅助工具,特别适用于C#开发者进行调试、处理正则表达式、网络请求以及系统交互等任务。它包含了一系列核心组件,如Socket通信、正则表达式操作、HTTP的...

    33位皇帝龙椅“坐歪”北京中轴线指向藏有玄机.pdf

    在长达7.8公里的轴线上,33位皇帝在此执掌天下,而这条中轴线的走向,却并非正南正北,而是有意偏离约2度十几分,偏离子午线约300米。这一偏斜并非偶然,而是包含了古代中国人的宇宙观、政治理念和科技水平。 中国...

    玄机论坛Msdn5_2016基础课程.pdf

    根据提供的文件信息,“玄机论坛Msdn5_2016基础课程.pdf”,我们可以推断这份文档主要涉及的是玄机论坛所提供的Msdn5-2016基础课程的相关内容。下面将从标题、描述、标签以及部分内容出发,详细阐述可能包含的知识点...

    股权交易藏隐情税务稽查破玄机.docx

    股权交易藏隐情税务稽查破玄机.docx

    玄机Box(C#开发强力助手).7z

    【标题】"玄机Box(C#开发强力助手).7z" 暗示这是一个专为C#开发者设计的工具集合,可能包含各种辅助库和工具,以提高开发效率和解决问题。这个压缩包可能是由程序员或团队为了方便共享和使用而创建的。 【描述】...

    玄机宝盒v1.4.2.9

    不会正则表达式却要使用? 常用字符串转换还要开网页? 想用C#写WIN32API找不到资料?想快速学习C#, 好多东西不知道怎么搜关键字,搜了一大堆也不对? C#开发个HTTP请求,写个注册机神马的,COOKIE,多线程太烦人,...

    玄机SocketDemo.7z

    我使用的是同步方式连接,海量数据并发不是靠异步就能解决的问题,在对学习Socket和想快速使用Socket的朋友来说,同步是很好的选择. 可同时接受5000+连接同时访问,而CPU消耗完全忽略不计.. 本着代码简洁,简单.通俗易懂...

    商品陈列藏玄机

    《商品陈列藏玄机》这份文档,作为超市管理学的重要组成部分,揭示了商品陈列对于超市经营的深远影响。商品陈列不仅是简单的摆放,更是一种策略,一种吸引顾客、提高销售的艺术。下面将详细阐述其中蕴含的知识点。 ...

    联阳it1169主控量产工具(UFDUtility)v3.4.3.1汉化版

    联阳的U盘主控!目前已知有162、163、165、167、168、190...难道个中暗藏玄机?!O(∩_∩)O哈哈~,不过今日无意在一个E文网站发现说明有支持联阳169主控的量产工具!最新UFDUtility_v3.4.3.1版,遗憾不是DtMPTool版!!

    精美影像背后的技术玄机

    精美影像背后的技术玄机 安捷伦科技公司传感器解决方案全球战略营销经理 Feisal Mosleh 影像是如何生成的? 在使用普通的传统相机时,光学系统把捕捉到的光打在胶卷上,随后人们就可以通过一个化学过程对其进行曝光...

    C#本人开发的彩票旋转矩阵选号杀号王双色球专用版1.5

    得彩易彩票旋转矩阵选号杀号王双色球专用版的问世,解决了您的烦恼,您只要下载使用了,软件就会主动成为您的好帮手,让您中奖不再是梦想! 本公司双色球项目开发小组根据组里多名长年研究彩票双色球的专家的成果,...

    ufdutility v3.4.3.1最新版量产工具(支持169主控).rar

    软件介绍: 联阳的U盘主控UFDUtility_v3.4.3.1版最新量产...难道个中暗藏玄机?!O(∩_∩)O哈哈~,不过今日无意在一个E文网站发现说明有支持联阳169主控的量产工具!最新UFDUtility_v3.4.3.1版,遗憾不是DtMPTool版!

    小学数学数学故事口香糖的玄机

    在一个充满神秘色彩的数学故事中,“口香糖的玄机”为我们揭开了一层神秘的面纱,向我们展示了数学在解决日常问题中的独特魅力。故事中的主人公山本四郎运用了数学思维和逻辑推理,在一场看似不可能的挑战中完成了...

Global site tag (gtag.js) - Google Analytics