前端实用工具|JavaScript 身份证号合法性校验工具类全解析

本文通过原生 JavaScript 实现一个完整、严谨的身份证号校验函数,支持 15 位和 18 位身份证号的判断。校验内容涵盖:

  • 格式校验:通过正则判断长度与基本结构;

  • 省份码校验:前两位数字是否为合法的行政区划代码;

  • /**
     * @description 校验身份证号是否合规(支持18位、15位)
     * @param {string | number} value 身份证号
     * @returns {boolean} true 合规;false 不合规
     */
    export default function checkPsidno(value) {
      const psidno = String(value).trim().toUpperCase()
    
      // 1. 校验身份证号格式和长度(15位或18位)
      const regPsidno = /^(?:\d{15}|\d{17}[0-9X])$/
      if (!regPsidno.test(psidno)) return false
    
      // 2. 校验省份编码
      const validProvinces = {
        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: '国外'
      }
    
      const provinceCode = Number(psidno.slice(0, 2))
      if (!validProvinces[provinceCode]) return false
    
      // 3. 校验出生日期是否有效
      const isValidBirthday = (year, month, day) => {
        const yyyy = Number(year)
        const mm = Number(month)
        const dd = Number(day)
    
        if (yyyy < 1800 || yyyy > new Date().getFullYear()) return false
        if (mm < 1 || mm > 12) return false
    
        const date = new Date(yyyy, mm - 1, dd)
        if (
          date.getFullYear() !== yyyy ||
          date.getMonth() + 1 !== mm ||
          date.getDate() !== dd
        ) return false
    
        const birthTime = date.getTime()
        const nowTime = Date.now()
    
        // 不允许出生日期晚于当前时间或年龄超过 150
        if (birthTime > nowTime || (new Date().getFullYear() - yyyy > 150)) return false
    
        return true
      }
    
      if (psidno.length === 15) {
        // 15位转换为18位时补全年号
        const match = psidno.match(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/)
        if (!match) return false
        const year = Number(match[2]) > 20 ? '19' + match[2] : '20' + match[2]
        if (!isValidBirthday(year, match[3], match[4])) return false
      }
    
      if (psidno.length === 18) {
        const match = psidno.match(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9X])$/)
        if (!match) return false
        if (!isValidBirthday(match[2], match[3], match[4])) return false
    
        // 4. 校验18位身份证最后一位校验码
        const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
    
        const sum = psidno
          .slice(0, 17)
          .split('')
          .reduce((acc, cur, idx) => acc + Number(cur) * weights[idx], 0)
    
        const expectedCheckCode = checkCodes[sum % 11]
        if (expectedCheckCode !== psidno[17]) return false
      }
    
      return true
    }
    

    出生日期校验:是否为合法的年月日,排除 2 月 30 日、4 月 31 日等非法日期;

  • 校验位校验(18位身份证):通过加权算法验证最后一位是否正确。

支持日常前端表单校验、Vue/React 表单校验规则集成,也适用于 Node.js 服务端初步过滤用户输入。

调用方式

import checkPsidno from './utils/checkPsidno' // 假设你将函数放在 utils 文件夹中

const idNumber = '11010519491231002X'

if (checkPsidno(idNumber)) {
  console.log('身份证号合法 ✅')
} else {
  console.log('身份证号不合法 ❌')
}

结语

本文分享了一个基于 JavaScript 编写的身份证号合法性校验工具类,支持 15 位与 18 位身份证号码校验,涵盖格式校验、出生日期验证、省份代码识别以及 18 位校验位的精确计算,实用性强,适合在前端表单验证等多个场景中复用。

希望这个工具类能帮你节省不少重复开发时间。如果你在使用过程中有更好的优化建议,或者希望我继续分享更多表单校验类工具,欢迎评论交流 !

如果觉得有用,点个 ⭐️ 收藏不迷路~

你可能感兴趣的:(前端,javascript,typescript)