身份证号的验证与解析

最近参加一些招聘,很多时候时候身份证号都会作为表单的一部分,需要用户进行填写。有些表单在填写了身份证号之后,还需要用户手动填写籍贯、性别、出生年月、以及年龄等信息,其实这些信息都在身份证号里面包含了。

身份证号的组成

要验证和解析身份证号,首先应该知道身份证号的组成。

省 市 区 年 月 日 序列号 校验位
XX XX XX XXXXX XX XX XXX X

身份证号可以划分成4部分,分别对应地区、出生年月、序列号、校验位。

  1. 第1-6位,对应具体到区(县)的地址,一般能够对生源地、籍贯等信息。
    区号与地区名的对照关系,有相关的类库可以进行对比。
    https://github.com/qianshou/district/blob/master/district-simple.sql
  2. 第7-14位,对应YYYY-mm-dd格式的出生年月。
  3. 第15-17位,对应顺序码,该地区同年同月同日生的人的编号,男性都是奇数,女性都是偶数。
  4. 第18位位校验位,对前面17为数字进行校验,检查身份证号的正确性。

具体的校验规则如下:

身份证号的前17位数,分别乘以规定参数,然后累计和除以11,得到的余数通过映射表进而得到校验位的值。

乘数参数表
7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2

余数映射表

余数 0 1 2 3 4 5 6 7 8 9 10
校验位 1 0 X 9 8 7 6 5 4 3 2

身份证号的验证

身份证号的验证,可以分为正则表达式的匹配验证和校验位的验证两部分。

由于身份证号的验证,在前端用的比较多,下面给出javascript的实现。

function checkIDNumber(id) {
    //兼容最后一位X大小写
    id = id.toUpperCase();
    //正则检查
    if(! /^[1-3]\d{16}[\d,X]$/.test(id)){
        return false;
    }
    //校验位检查
    var vcode = id[id.length-1];
    var params = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
    var map = ['1','0','X','9','8','7','6','5','4','3','2'];
    var sum = 0;
    for(var i=0;i<params.length;i++){
        sum += id[i]*params[i];
    }
    var remainder = sum%11;
    if(vcode == map[remainder]){
        return true;
    }else{
        return false;
    }
}

身份证号的解析

在函数checkIDNumber的基础上进行修改,实现身份证号的检查与解析。

var district_map = require('./district-simple.json');
function parseIDNumber(id) {
    //兼容最后一位X大小写
    id = id.toUpperCase();
    //正则检查,并获取相关信息
    var data = /^([1-3]\d{5})(\d{8})(\d{3})([\d,X])$/.exec(id);
    if(!data){
        return false;
    }
    //校验位检查
    var vcode = id[id.length-1];
    var params = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
    var map = ['1','0','X','9','8','7','6','5','4','3','2'];
    var sum = 0;
    for(var i=0;i<params.length;i++){
        sum += id[i]*params[i];
    }
    var remainder = sum%11;
    if(vcode != map[remainder]){
        return false;
    }
    var ret = [];
    //获取地区信息
    var district = [];
    var discode = data[1];
    var provcode = discode.substring(0,2)+'0000';
    var citycode = discode.substring(0,4)+'00';
    if(typeof district_map[provcode] != "undefined"){
        district.push(district_map[provcode])
    }
    if(typeof district_map[citycode] != "undefined"){
        district.push(district_map[citycode]);
    }
    if(typeof district_map[provcode] != "undefined"){
        district.push(district_map[discode]);
    }
    ret['district'] = district;
    //获取出生日期
    var birth_date = data[2];
    var year = parseInt(birth_date.substring(0,4));
    var month = parseInt(birth_date.substring(4,6));
    var day = parseInt(birth_date.substring(6,8));
    var birth = [year,month,day];
    ret['birth'] = birth;
    //获取年龄
    var date = new Date();
    var year_diff = date.getFullYear()-year;
    var month_diff = date.getMonth()+1-month;
    var day_diff = date.getDate()-day;
    var age = year_diff;
    if(month_diff<0 || (month_diff==0&&day_diff<0)){
        age--;
    }
    ret['age'] = age;
    //获取性别信息
    var serno = data[3];
    var sex = serno%2;
    ret['sex'] = sex;
    return ret;
}

为了方便调用,我将sql语句中的区号和名称的对应关系,生成了相关的json文件。在该函数的实现中,为了方便调用,采用了node.js的引入机制使用的json文件,如果在前端JavaScript调用时,可以采用ajax请求引入json文件信息,然后进行匹配。

https://github.com/qianshou/district/blob/master/district-simple.json

猜你喜欢

转载自blog.csdn.net/koastal/article/details/77852482
今日推荐