探究from表单的身份证号码的校验逻辑 javascript

start

  • 最近番茄学习前端八股文,学的有些乏味了。随即在应用商店下载了几个小游戏,准备把玩放松一下。
  • 众所周知,现在玩游戏都是要身份证实名认证的,但是我又有精神洁癖,不想把自己的身份证提供给这种小作坊。
  • "输入"一个身份证号码?番茄尝试了很多次,但是它的表单校验却一直无法通过。我很好奇!它这校验咋写的,走我们手撕一个去。

目标

  1. 了解身份证号码的规则
  2. 编写正则

研究一下身份证号码的格式

在这里插入图片描述

  1. 我们的身份证号码是长度为18的字符串,除了最后一位可能为字母x0-9数字,其他每一位都由0-9数字组成。
  2. 每一位数字的意义:

    1、省份
    前1、2位数字表示:所在省份的代码。
    2、城市
    第3、4位数字表示:所在城市的代码。
    3、区县
    第5、6位数字表示:所在区县的代码。
    4、出生日期
    第7~14位数字表示:出生年、月、日。
    5、顺序码
    第15、16、17位数字表示 ,顺序码奇数表示男性,偶数表示女性
    6、校检码
    第18位数字是校检码:用来检验身份证的正确性。校检码可以是0~10的数字,10用x表示。校验码是根据前面17位数字根据计算规则得出来的数字(具体的计算规则后面会说到)

说句题外话

  • 按照上述的规则,一个刚出生孩子,其实他的身份证账号的绝大部分都是固定的。比如省市县,比如出生日期,比如说校验码。
  • 又考虑到每个人的身份证号码是唯一的,所以除去出生地的问题,除去性别的问题,所以一个县一天最多只能出生500个男孩或者500个女孩。
  • 那假如一个县同一天内出生的男孩/女孩数量超过的500怎么办?那不是身份证号码不唯一了?

有人简略推算过,发生这种情况的概率暂时比较低,如果真的有一天,一个县一天内出生的孩子超过1000,可以人为的将生日往后推迟一天,当然这只是我的猜测。

编写正则

1.简单的身份证校验

var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;

2.进一步限制

   // 校验最基本的位数规则,以及校验`校验码`
   var checkCode = function (val) {
      var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
      var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
      var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
      var code = val.substring(17);
      if (p.test(val)) {
        var sum = 0;
        for (var i = 0; i < 17; i++) {
          sum += val[i] * factor[i];
        }
        if (parity[sum % 11] == code.toUpperCase()) {
          return true;
        }
      }
      return false;
    }
    // 校验年月日 
    var checkDate = function (val) {
      var pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
      if (pattern.test(val)) {
        var year = val.substring(0, 4);
        var month = val.substring(4, 6);
        var date = val.substring(6, 8);
        var date2 = new Date(year + "-" + month + "-" + date);
        if (date2 && date2.getMonth() == (parseInt(month) - 1)) {
          return true;
        }
      }
      return false;
    }

    // 校验省份编码
    var checkProv = function (val) {
      var pattern = /^[1-9][0-9]/;
      var provs = { 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: "澳门" };
      if (pattern.test(val)) {
        if (provs[val]) {
          return true;
        }
      }
      return false;
    }

    var checkID = function (val) {
      if (checkCode(val)) {
        var date = val.substring(6, 14);
        if (checkDate(date)) {
          if (checkProv(val.substring(0, 2))) {
            return true;
          }
        }
      }
      return false;
    }

校验码生成规则?

// 获取校验码  (这里为了方便演示,就单独把这逻辑抽离出来了,暂不考虑参数的异常情况,建议先正则匹配完基本字段结构再做校验码校验)
	function getCheckCode(val) {
	  // 加权因子
	  let factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
	
	  // 校验码
	  let parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
	
	  let sum = 0
	  for (var i = 0; i < 17; i++) {
	    sum += val[i] * factor[i]
	  }
	
	  // 校验码校验规则: (前17项每一项 * 对应位数的加权因子) 累加,除以11求余,再对应校验码数组的索引。
	  return parity[sum % 11]
	}
	
	console.log('测试数据', getCheckCode('13082119660231557'))  //'测试数据'  1

参考文章:

  1. 身份证号码的正则表达式及验证详解(JavaScript,Regex)

end

  • 所以在 研究一下身份证号码的格式章节截图的身份证账号的校验码应该为1,相信这样的身份证号码,妥妥的可以通过前端页面校验了。ღ( ´・ᴗ・` )
  • 在我生成合格的身份证账号后,打开小作坊的游戏,输入身份证号码,点击提交,它提示我,姓名和身份证账号不一致。。。。。
  • o(╥﹏╥)o哭晕在厕所,拜拜了你嘞。不玩了,学前端去。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lazy_tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值