1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* @Description:身份证校验规则.
* @Version: 1.0
* @Author: dracula
* @Date: 2021-09-28
*/
//在需要身份校验的vue组件中导入这个js文件,调用暴露出去的校验方法。传入的参数为用户输入的身份证号
//校验身份证号
export function isIdentityId(identityId) {
var patrn = /(^\d{15}$)|(^\d{17}(\d|X|x)$)/;//长度或格式校验
//地区校验
var aCity = {
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: "国外"
};
// 出生日期验证
var sBirthday = (
identityId.substr(6, 4) +
"-" +
Number(identityId.substr(10, 2)) +
"-" +
Number(identityId.substr(12, 2))
).replace(/-/g, "/"),
d = new Date(sBirthday)
// 身份证号码校验 最后4位 包括最后一位的数字/字母X
var sum = 0,
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
codes = "10X98765432";
for (var i = 0; i < identityId.length - 1; i++) {
sum += identityId[i] * weights[i];
}
var last = codes[sum % 11]; //计算出来的最后一位身份证号码
var errorMsg = '';
if (identityId === '') {
errorMsg = "身份证号不能为空"
} else if (!patrn.exec(identityId)) {
errorMsg = "您输入的身份证长度或格式错误"
} else if (!aCity[parseInt(identityId.substr(0, 2))]) {
errorMsg = "您输入的身份证地区非法"
} else if (sBirthday != d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()) { errorMsg = "身份证上的出生日期非法" } else if (identityId[identityId.length - 1] != last) {
errorMsg = "您输入的身份证号非法"
}
return errorMsg;
}
/**
* @description : 校验身份证号是否合规(18位、15位)
* @param {String|Number} value
* @return {Boolean} true-合规 false-不合规
*/
export function checkCertId(value) {
const psidno = String(value)
// 1.校验身份证号格式和长度
const regPsidno = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[X])$)$/
if (!regPsidno.test(psidno)) {
return false
}
// 2.校验前两位的省份编码是否正确
const province = { 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: '国外' }
if (!province[Number(psidno.slice(0, 2))]) {
return false
}
// 3.校验出生日期
if (psidno.length === 15) {
// 15位号码 省(2位)市(2位)县(2位)年(2位)月(2位)日(2位)校验码(3位)
const reg = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/)
const arrSplit = psidno.match(reg)
// 15位号码在年份前补 19 或 20
const year = Number(arrSplit[2].charAt(0)) > 0 ? '19' + arrSplit[2] : '20' + arrSplit[2]
const month = arrSplit[3]
const day = arrSplit[4]
if (!validateBirthday(year, month, day)) {
return false
}
} else if (psidno.length === 18) {
// 18位号码 省(2位)市(2位)县(2位)年(4位)月(2位)日(2位)校验码(4位)
const reg = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/)
const arrSplit = psidno.match(reg)
const year = arrSplit[2]
const month = arrSplit[3]
const day = arrSplit[4]
if (!validateBirthday(year, month, day)) {
return false
}
} else {
return false
}
// 校验出生日期是否合理
function validateBirthday(year, month, day) {
year = Number(year) // 年
month = Number(month) // 月
day = Number(day) // 日
const nowTime = new Date().getTime() // 当前时间戳
const birthTime = new Date(`${year}-${month}-${day}`).getTime() // 获取出生日期的时间戳
// 不能是明天出生的吧
if (birthTime > nowTime) {
return false
}
// 一般人活不到150岁吧
const nowYear = new Date().getFullYear()
if ((nowYear - year) > 150) {
return false
}
// 不能是13月出生的吧
if (month < 1 || month > 12) {
return false
}
// 不能是2月30号、4月31号、5月32号出生的吧
const date = new Date(year, month, 0) // 获取当月的最后一天
if (day < 1 || day > date.getDate()) {
return false
}
return true
}
// 4.18位号码校验生成的校验码
if (psidno.length === 18) {
const Wi = [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
for (let i = 0; i < 17; i++) {
sum += Number(psidno.charAt(i)) * Wi[i]
}
if (parity[sum % 11] !== psidno[17]) {
return false
}
}
return true
}