比较严谨的检验身份证号的真实性与合法性

我们都知道,身份证号是我们每个人的唯一的标识,既然要做到唯一性,身份证号的设计肯定不会仅仅只是设计成18位,最后一位是数字或者“X”这么简单,仅仅只是这么来设计就太low了,而且很容易出现重复的情况,先看看身份证号每一位代表的意思


身份证号码各位数字代表含义

身份证号码各位数字代表含义

再看看身份证号的校验计算方法

身份证号校验计算方法

1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]。

2、将这17位数字和系数相乘的结果相加。

3、用加出来和除以11,看余数是多少。

4、余数只可能有[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]这11个数字。其分别对应的最后一位身份证的号码为[1, 0, ‘X’, 9, 8, 7, 6, 5, 4, 3, 2]。(即余数0对应1,余数1对应0,余数2对应X…)

5、通过上面得知,如果余数是3,即身份证的第18位数字就是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。

上代码(对照上面身份证号校验计算方法看代码)

  IdentityCodeValid(code) {
    const city = {
      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: '国外',
    };
    let pass = true; // 验证失败返回false
    if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
      pass = false;
    } else if (!city[code.substr(0, 2)]) {
      pass = false;
    } else if (code.length === 18) {
      // 18位身份证需要验证最后一位校验位
      code = code.split('');
      // ∑(ai×Wi)(mod 11)
      // 加权因子
      const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
      // 校验位
      const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
      let sum = 0;
      let ai = 0;
      let wi = 0;
      for (let i = 0; i < 17; i++) {
        ai = code[i];
        wi = factor[i];
        sum += ai * wi;
      }
      if (String(parity[sum % 11]) !== String(code[17].toUpperCase())) {
        pass = false;
      }
    }
    return pass;
  }

正则:/^\d{6} (18|19|20)?\d{2} (0[1-9]|1[012]) (0[1-9]|[12]\d|3[01]) \d{3} (\d|X)$/

正则解释:
/^\d{6} : 以6个数字开始
(18|19|20)?\d{2} : 年
(0[1-9]|1[012]) : 月
(0[1-9]|[12]\d|3[01]) : 日
\d{3} : 3位数字
(\d|X)$/ : 以一个数字或者X结尾

正则参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值