-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
20202020 年撰写2020 年撰写JS与 JavaScript、ECMAScript 相关的文章与 JavaScript、ECMAScript 相关的文章代码片段记录一些代码片段记录一些代码片段
Description
关于国家公民身份号码规定如下:
/**
* 〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定:
* 公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
*
* 地址码编码规则为:
* 第一位数字表示地区,1 是华北,2 是东北,3 是华东,4 是中南,5 是西南,6 是西北。
* 第二位数字表示户籍地所在的直辖市、省、自治区,比如在华北地区,1 代表北京市,2 代表天津市等。
* 第三、四位数字则表示户籍所在地的区、县、县级市、旗。
* 第五、六位数字是户籍所在地。
*
* 出生日期码:
* 身份证号码第七位到第十四位表示编码对象出生的年、月、日。
*
* 顺序码:
* 身份证号码第十五位到十七位是顺序码,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。
*
* 校验码:
* 身份证号码最后一位为校验码。
*
* 校验码的计算方法:
* 一、将身份证号码前面的 17 位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
* 二、将这 17 位数字和系数相乘的结果相加。
* 三、用加出来的和除以 11,余数只可能有:0-1-2-3-4-5-6-7-8-9-10 这 11 个数字。其分别对应的最后一位身份证的号码为:1-0-X -9-8-7-6-5-4-3-2。
* 四、如果余数是 2,那么身份证的第 18 位数字就是 X。
*/
身份证校验的 JavaScript 实现如下:
/**
* 支持 15 位和 18 位身份证号校验
* 关于身份证号更多规则,请看文件末尾
*
* @param {string} code 身份证号码
* @returns {boolean} 是否检验通过
*/
export const checkIDNumber = code => {
if (!code || typeof code !== 'string') return false
// prettier-ignore
const provinceCodes = ['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 reg = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/i
const codeLen = code.length
// 格式错误
if (!reg.test(code) || ![15, 18].includes(codeLen)) {
return false
}
// 地址码错误
const provinceCode = code.substring(0, 2)
if (!provinceCodes.includes(provinceCode)) {
return false
}
// 18 位需校验最后一位校验码
if (codeLen === 18) {
const codeArr = code.split('')
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
let sum = 0
let ai = 0
let wi = 0
for (let i = 0; i < 17; i++) {
ai = codeArr[i]
wi = factor[i]
sum += ai * wi
}
if (parity[sum % 11] != codeArr[17].toUpperCase()) {
// 校验码错误
return false
}
}
return true
}
/**
* 〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定:
* 公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
*
* 地址码编码规则为:
* 第一位数字表示地区,1 是华北,2 是东北,3 是华东,4 是中南,5 是西南,6 是西北。
* 第二位数字表示户籍地所在的直辖市、省、自治区,比如在华北地区,1 代表北京市,2 代表天津市等。
* 第三、四位数字则表示户籍所在地的区、县、县级市、旗。
* 第五、六位数字是户籍所在地。
*
* 出生日期码:
* 身份证号码第七位到第十四位表示编码对象出生的年、月、日。
*
* 顺序码:
* 身份证号码第十五位到十七位是顺序码,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。
*
* 校验码:
* 身份证号码最后一位为校验码。
*
* 校验码的计算方法:
* 一、将身份证号码前面的 17 位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
* 二、将这 17 位数字和系数相乘的结果相加。
* 三、用加出来的和除以 11,余数只可能有:0-1-2-3-4-5-6-7-8-9-10 这 11 个数字。其分别对应的最后一位身份证的号码为:1-0-X -9-8-7-6-5-4-3-2。
* 四、如果余数是 2,那么身份证的第 18 位数字就是 X。
*
* 示例:
* 某女性的身份证号码为【11010519491231002X】, 我们看看这个身份证是不是合法的身份证。
* 首先我们得出前 17 位的乘积和【(1*7)+(1*9)+(0*10)+(1*5)+(0*8)+(5*4)+(1*2)+(9*1)+(4*6)+(9*3)+(1*7)+(2*9)+(3*10)+(1*5)+(0*8)+(0*4)+(2*2)】是 167,
* 然后用 167 除以 11 得出的结果是 167/11=15----2,也就是说其余数是 2。
* 最后通过对应规则就可以知道余数 2 对应的检验码是 X。
* 所以,可以判定这是一个正确的身份证号码。
* 请知悉,示例中身份证号码来自国家标准文件附录,请勿非法使用,否则后果自负!
*
* 附上:
* 〖中华人民共和国国家标准 GB 11643-1999〗:http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=080D6FBF2BB468F9007657F26D60013E
* 关于身份证校验码,可以看:https://baike.baidu.com/item/身份证校验码/3800388
*
* 其他:
* 相比 18 位的身份证号码,15 位的身份证号少了出入年份的前两位,以及最后的校验位。因此将你现在的身份证号码去掉这三位数字,使用本方法也可校验通过
*/
// 地址码前两位,所对应的省市:
// const provinceCodes = {
// 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: '国外'
// }
此方法已收录至:toFrankie/javascript-utils,还有其他一些比较实用的方法,比如中文转拼音等,请看这里。
The end.
Metadata
Metadata
Assignees
Labels
20202020 年撰写2020 年撰写JS与 JavaScript、ECMAScript 相关的文章与 JavaScript、ECMAScript 相关的文章代码片段记录一些代码片段记录一些代码片段