js 校验身份证姓名及号码

您所在的位置:网站首页 博朗剃须刀5系和7系的区别 js 校验身份证姓名及号码

js 校验身份证姓名及号码

2023-11-02 05:46| 来源: 网络整理| 查看: 265

js 校验身份证姓名及号码

最近在项目中遇到了关于身份证姓名和 id 的校验,特此记录。

姓名校验

首先明确校验规则,中国人的姓名,无非就是汉字+长度校验。这可很简单,随便去网上搜一下汉字校验,千篇一律的以下代码:

/^[\u4e00-\u9fa5]+$/

看起来好像没什么问题,实际测试好像也没什么问题。但是我们也知道,中国汉字是一直在增加的,对应的 unicode 编码也是一直在增加的。当然,我们可以手动把后续新增的 uncode 编码都加上,类似下面这样:

/^[\u4e00-\u9fa5\uF900-\uFA2D]+$/

但是这样也还是很繁琐,而且随着时间的推移需要不停的去维护这个函数。有没有什么更好的方式呢?

答案是有的

/^[\p{Unified_Ideograph}]$/u

其中\u是 正则表达式标志,表示正则表达式中的字符串按照 unicode 编码处理,\p则会根据 Unicode 属性进行匹配,后面需要跟着一个 Unicode 属性值,以这种格式\p{Unicode属性格式},由于 Unicode 属性值太多,这里不一一列举了,感兴趣的可以看这里, 这里我们使用Unified_Ideograph这个属性值,表示各种汉字字符。

ok, 大功告成了,现在我们不需要知道汉字的 unicode 编码范围也能匹配到汉字了,并且我们无需手动维护,这个正则是长久有效的。

兼容性

本身\p的兼容性还是可以的,如果需要兼容更低版本的浏览器,可以手动配置 babel 的 plugin

plugins: [ [ '@babel/plugin-proposal-unicode-property-regex', { useUnicodeFlag: false } ] ]

这个 plugin 还提供了一个在线的demo,方便更直观的看到转义之后的结果。

身份证号校验

关于身份证号的验证比较简单,先去网上查一下身份证的组成规则。

针对二代身份证,一共 18 位,前面 6 位表示省市区,中间 8 位表示年月日,然后是 3 位随机数,最后一位是校验码。

对于一代身份证,一共 15 位,年份少两位,没有最后一位校验码。所以无非就是需要校验省市区,年月日和校验码。

详细规则参考百度百科。

格式化

为了后续校验函数的统一,我们首先针对一代身份证做一个格式化

function normalId(id) { // 15位:年份只有后两位,没有校验码 if (id.length === 15) { const id17 = id.substring(0, 6) + '19' + id.substring(6); return id17 + getCode(id17); } }

我们在年份那里手动拼接上了19,然后手动计算出最后一位校验码拼接到末尾,这个getCode函数我们后面会提到,这里先不细说。

省市区校验

省市区一共有 6 位,前两位表示省级行政区,一共 34 个,简单观察了一下,还算有点规律,就简单校验了一下,至于市和区的校验,没什么校验的必要性。

function checkAddress(id: string): boolean { const re = /^1[1-5]|2[123]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|71|81|82$/; return re.test(id.substring(0, 2)); } 出生年月日校验

这里主要校验两点,日期小于当前日期,并且是一个合法日期

function checkBirth(str: string): boolean { // 小于当前日期,并且日期合法 const now = new Date(); const [_, year, month, day] = /(\d{4})(\d{2})(\d{2})/.exec(str); const realDate = new Date(+year, +month - 1, +day); const realYear = realDate.getFullYear(); const realMonth = realDate.getMonth() + 1; const realDay = realDate.getDate(); return ( realDate < now && +year === realYear && +month === realMonth && +day === realDay ); } 校验码校验

这个校验码是由前面的 17 位通过某种计算的出来的,计算规则参考 👆 百度百科,我们只需要手动计算一下然后和用户输入的做一个对比即可:

// 每一位的加权数 const powerMap = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; // 余数对应的最后一位校验码 const codeMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; // 计算正确的校验码 function getCode(str: string): string { let sum = 0; for (let i = 0; i < 17; i++) { sum += +str[i] * powerMap[i]; } return codeMap[sum % 11]; } // 对比校验码 function checkCode(id: string): boolean { const rightCode = getCode(id); return id.slice(-1) === rightCode; } 完

大概就这些,感谢阅读,👦

参考资料

jhuang.me/2018/01/26/… baike.baidu.com/item/%E5%B1…


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3