本文通过原生 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 位校验位的精确计算,实用性强,适合在前端表单验证等多个场景中复用。
希望这个工具类能帮你节省不少重复开发时间。如果你在使用过程中有更好的优化建议,或者希望我继续分享更多表单校验类工具,欢迎评论交流 !
如果觉得有用,点个 ⭐️ 收藏不迷路~