揭开身份证验证的神秘面纱

正则验证身份证号码

HTML5学堂:曾经一直觉得用正则验证身份证号码是很简单的~但是,当真正挖掘身份证号码的规则之后,才发现,想要写好一个正则验证也没有那么容易。最近一周利利出差,所以,只能周六跟大家一起分享一下自己的研究结果啦~

身份证的规则

书写一个正则之前,需要先了解一下身份证的基本规则

  1. /*
  2. * 身份证18位编码规则:dddddd yyyymmdd xxx y
  3. * dddddd:6位地区编码
  4. * yyyymmdd: 出生年(四位年)月日,如:19910215
  5. * xxx:顺序编码,系统产生,无法确定,奇数为男,偶数为女
  6. * y: 校验码,该位数值可通过前17位计算获得
  7. * HTML5学堂出品 http://www.h5course.com 请尊重原创
  8. * 前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
  9. * 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
  10. * 如果验证码恰好是10,为了保证身份证是十八位,那么第十八位将用X来代替
  11. */

校验位计算方法:身份证前17位,每一位数字和相应位数的加权因子进行乘法运算,之后求和(17项之和),再用这个和对11取余,所得的余数作为“验证位数组Y”的下标,也就是Y[余数],找到“验证位数组Y”中的相应数字,如果身份证最后一位和这个数字吻合,则身份证号码合法(如果最后一位是X/x,就对应于“验证位数组Y”中的10这个数字)

简单的号码计算小例子

假如是这个身份证号码(这个身份证号码是我瞎编的):110203198811120342。

于是,复杂的计算开始了。取出身份证前17位,与[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]中对应的位分别进行乘法运算,于是乎:

sum = 1 * 7 + 1 * 9 + 0 * 10 + 2 * 5 + ... + 3 * 4 + 4 * 2。

我们能够计算出来,总和为177。之后用177对11取余,余数为1。那么在[1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]数组中,下标为1的元素就是第二个元素,也就是数值为0。此时将0与身份证号的最后一位(2)做比较,很明显,错误,那么也证明了这个号码是我瞎编的了……

验证身份证号码的正则如何写?

身份证规则

我们将一个身份证号码拆开:身份证18位编码规则:dddddd yyyymmdd xxx y

1) dddddd:6位地区编码,地区编码没有以0开头的,举一个例子,北京用的就是110开头,河北用的就是130开头,福建省用的是350开头,此类。

2) yyyymmdd: 出生年(四位年)月日,前四位是年份,没啥可说的,月份只能是01~12,日期只能是01~31

3) xxx:三位数字

4) y: 校验码,0~9以及X(有时有人会写成x)

相对应的正则出炉喽

1) 地区编码:[1-9]\d{5}

2) 出生年份:[1-9]\d{3}

3) 出生月份:((0[1-9])|(1[0-2]))

4) 出生日期:((0[1-9])|([1-2]\d)|(3[0-1]))

5) 最后四位:((\d{4})|(\d{3}[Xx]))

完整匹配身份证号码的正则

于是乎,完整匹配身份证号码的正则华丽丽的诞生了~~~

  1. var reg = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))((\d{4})|(\d{3}[Xx]))$/;

完了吗?别急,往下接着看~~~

使用JS增强号码的可控性

利利此处采用的是返回对象的设置方式,主要是便于获取完整的信息,需要注意的就是要在返回时提供比较合理的API了,不然对方是看不懂滴~~~

我们希望用户通过调用验证身份证号码的方法,不仅仅能够得到是否正确,还能够得到更加详细的信息。所以,一起先来看代码喽~

/*
* 功能:验证身份证是否可用,如果可用,则提取生日、性别等信息
* 参数:传入一个字符串或者一个数字均可
* 返回:包含基本信息的对象
* 作者:HTML5学堂 http://www.h5course.com
*/
function regIDAllInf(str){
    str = str.toString();
    var reg = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))((\d{4})|(\d{3}[Xx]))$/;
    // 用于存储结果
    var result = {};
    if (reg.test(str)) {
        var sum = 0;
        var arrID = str.split("");
        var arrWi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        var arrY = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];
        for (var i = 0; i < arrWi.length; i++) {
            sum += arrID[i] * arrWi[i];
        };
        sum %= 11;
        var lastID = arrID[arrID.length - 1];
        if (lastID == "X" || lastID == "x") {
            lastID = 10;
        };
        if (arrY[sum] == lastID) {
            result["check"] = true;
            result["birthday"] = str.substr(6, 8);
            result["cityCode"] = str.substr(0, 6);
            result["gender"] = (str.substr(14, 3) % 2 == 0) ? "女" : "男";
        } else {
            result["check"] = false;
            result["error"] = "身份证号码输入错误";
        }
    } else {
        result["check"] = false;
        result["error"] = "身份证号码格式有误";
    }    
    return result;
}
console.log(regIDAllInf(str)); // 此处请将str替换为身份证号码进行测试

如果格式正确,会返回匹配正确,并返回性别、区域、生日的信息。如果错误,也会根据情况返回不同的错误提示信息。

本文章内容小编:HTML5学堂-利利。耗时4h~

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-03-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落影的专栏

程序员进阶之算法练习(十六)

前言 正文6道题目来自leetcode––为求职为生的编程网站,目的是工作闲暇之时锤炼代码功底。 没有捷径,但手熟尔; 一步领先,步步领先。 正文 5. L...

3615
来自专栏xingoo, 一个梦想做发明家的程序员

在Elasticsearch中查询Term Vectors词条向量信息

这篇文章有点深度,可能需要一些Lucene或者全文检索的背景。由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正。 更多内容还请参考整理的E...

19810
来自专栏IT派

Javascript 将 HTML 页面生成 PDF 并下载

最近碰到个需求,需要把当前页面生成 pdf,并下载。弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :)

681
来自专栏老马寒门IT

08-移动端开发教程-移动端适配方案

由于移动端的特殊性,屏幕的尺寸碎片化严重,要想很好的适配不同的尺寸的设备,需要我们前端开发相比PC端要做一些基层的适配方案。

41010
来自专栏数说工作室

正则表达式的“阿赖耶识”| 【SAS Says·扩展篇】正则表达式

阿赖耶识...为宇宙万有之本,含藏万有,使之存而不失,故称藏识。又因其能含藏生长万有之种子,故亦称种子识。 ——《佛光大辞典》 佛家说人有九识,除眼、耳、鼻、舌...

3173
来自专栏老马寒门IT

08-移动端开发教程-移动端适配方案

由于移动端的特殊性,屏幕的尺寸碎片化严重,要想很好的适配不同的尺寸的设备,需要我们前端开发相比PC端要做一些基层的适配方案。 1. 常见的适配方案 百分比+固定...

3056
来自专栏华章科技

10个非常实用的Excel技巧

Excel可以说是MS Office系列中最神奇也最重要的软件。对于专业的职场人士,工作中经常需要用到Excel来分析数据。亲们别再傻傻地用鼠标点来点去啦,用这...

1388
来自专栏小工匠技术圈

【Java小工匠聊密码学】--非对称加密--RSA1

  RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(...

553
来自专栏转载gongluck的CSDN博客

python笔记:#007#变量

变量的基本使用 程序就是用来处理数据的,而变量就是用来存储数据的 目标 变量定义 变量的类型 变量的命名 01. 变量定义 在 Python 中,每个变量 在...

2938
来自专栏java学习

面试题64(有1千万条有重复的短信,以文本文件的形式保存,一行一条,也有重复。请用5 分钟时间找出重复出现最多的前10 条短信)

1·有1千万条有重复的短信,以文本文件的形式保存,一行一条,也有重复。请用5 分钟时间找出重复出现最多的前10 条短信。? 正确解析如下... 解析: 对于本题...

2588

扫描关注云+社区