zoukankan      html  css  js  c++  java
  • 身份证号码的正则校验+升级版

    需求

    验证一个身份证号码, 很简单的需求
    本来想搜一个正则,结果发现,错误的太多了,只能自己试着写

    网上的一个方法(垃圾,不要用)

    function check (val) {
        var reg = /[1-9]d{14}|[1-9]d{17}|[1-9]d{16}x/  // 匹配14位或者17位或 16位数字后面加个x的
        return reg.test(val)
    }
    

    解读正则

    [1-9]d{14} 匹配14位数字
    [1-9]d{17} 匹配17位数字
    [1-9]d{16}x 匹配16位数字后面跟x

    console.log(check('1111111111111111111111')) // true 这种鬼玩意都能匹配上
    

    自己写一个简单的

    在写之前先研究下身份证的结构,这里只研究18位的,因为15位的已经过期了!

    分析

    xxxxxx yyyy mm ddd nnn v 十八位

    xxxxxx地区: [1-9]d{5}
    年的前两位: (18|19|20)
    年的后两位: d{2}
    月份: ((0[1-9])|(10|11|12))
    天数: (([0-2][1-9])|10|20|30|31)
    顺序码: d{3}
    验证码: [0-9Xx]

    正则表达: ^[1-9]d{5}(18|19|20)d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$

    function check (val) {
        var reg = /[1-9]d{14}|[1-9]d{17}|[1-9]d{16}x/  // 匹配14位或者17位或 16位数字后面加个x的
        return reg.test(val)
    }
    
    
    console.log(check('610102218801012344')) //年不对 false  610102  2188  01 01 234 4 
    
    console.log(check('610102198801012344')) //true               610102  1988  01 01 234 4  
    

    升级版验证

    身份证的前6位代表地区
    对应表 验证中国身份证 前6位对应地区码

    校验码的计算方法

    某男性的身份证号码是340523198001010013。我们要看看这个身份证是不是合法的身份证。
    1.17位分别乘不同系数 let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]结果相加
    2. 加出来除以11,看余数
    3. 余数对应数组 let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']的位置的值

    举个例子

    首先我们得出前17位的乘积和:
    (3*7+4*9+0*10+5*5+2*8+3*4+1*2+9*1+8*6+0*3+0*7+1*9+0*10+1*5+0*8+0*4+1*2) = 185
    然后再求余:
    185 % 11 = 9
    最后通过对应规则就可以知道余数9对应的数字是3。所以,可以判定这是一个合格的身份证号码。
    
    function check(val) {
      const city = { '110000': '北京市',
        '110100': '北京市市辖区',
        '110101': '北京市东城区',
        '110102': '北京市西城区'........ }  // 对应的地区码 上面有,数据太多这里省略
    
      // 类型转换
      let id = parseInt(val, 10)
      // 正则判断基本类型
      if (!/^d{17}(d|x)$/i.test(id)) return false
      // 地区的判断
      if (city[id.substr(0, 6)] === undefined) return false
      // 生日
      let birthday = id.substr(6, 4) + '/' + Number(id.substr(10, 2)) + '/' + Number(id.substr(12, 2))
      let d = new Date(birthday)
      let newBirthday = d.getFullYear() + '/' + Number(d.getMonth() + 1) + '/' + Number(d.getDate())
      let currentTime = new Date().getTime()
      let time = d.getTime()
      if (time >= currentTime || birthday !== newBirthday) return false
      // 判断校验码
      let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
      let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
      let sum = 0
    
      for (let i = 0; i < 17; i++) {
        sum += id.substr(i, 1) * arrInt[i]
      }
      let residue = arrCh[sum % 11]
      if (residue !== id.substr(17, 1)) return false
    
      return true 
    }
    
  • 相关阅读:
    无语的Filezilla
    服务无法启动集中帖
    FileZilla Server-Can’t access file错误解决方法
    CCNA2.0笔记_OSPF v3
    CCNA2.0笔记_OSPF v2
    <转>32位移植到64位 注意事项
    异步设备IO 《windows核心编程》第10章学习
    关于自己五年来做出的选择分析
    2015过年之前计划
    关于同一线程两次调用EnterCriticalSection的测试
  • 原文地址:https://www.cnblogs.com/mayufo/p/8304929.html
Copyright © 2011-2022 走看看