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