note/tech/身份证校验.md
2025-11-19 10:16:05 +08:00

114 lines
3.8 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 身份证校验js & shell
```javascript
var checkProv = function (val) {
var pattern = /^[1-9][0-9]/;
var provs = {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:"澳门"};
if(pattern.test(val)) {
if(provs[val]) {
return true;
}
}
return false;
}
var checkDate = function (val) {
var pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
if(pattern.test(val)) {
var year = val.substring(0, 4);
var month = val.substring(4, 6);
var date = val.substring(6, 8);
var date2 = new Date(year+"-"+month+"-"+date);
if(date2 && date2.getMonth() == (parseInt(month) - 1)) {
return true;
}
}
return false;
}
var checkCode = function (val) {
var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
var code = val.substring(17);
if(p.test(val)) {
var sum = 0;
for(var i=0;i<17;i++) {
sum += val[i]*factor[i];
}
if(parity[sum % 11] == code.toUpperCase()) {
return true;
}
}
return false;
}
var checkID = function (val) {
if(checkCode(val)) {
var date = val.substring(6,14);
if(checkDate(date)) {
if(checkProv(val.substring(0,2))) {
return true;
}
}
}
return false;
}
//输出 true
console.log(checkID("11010519491231002X"));
//输出 false校验码不符
console.log(checkID("110105194912310021"));
//输出 false日期码不符
console.log(checkID("110105194902310026"));
//输出 false地区码不符
console.log(checkID("160105194912310029"));
```
## shell的身份证判断
```bash
#!/bin/bash
# 获取用户输入的身份证号码
while :
do
read -p "请输入身份证号码(Ctrl+C Exit): " idcard
#身份证号码正则表达式
idcard_regex="^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)[0-9]{3}[0-9Xx]$"
#判断正则表达
if [[ $idcard =~ $idcard_regex ]]; then
echo "身份证号码合法,开始判断日期是否合法......"
birthday=${idcard:6:4}-${idcard:10:2}-${idcard:12:2}
timestamp=$(date -d "$birthday" +%s 2>/dev/null)
if [ $? -ne 0 ]; then
echo "输入的日期不合法,请重新输入。"
else
echo "输入的日期合法,开始判断校验位......"
# 提取出身份证号码中的前 17 位
idcard17=${idcard:0:17}
# 计算校验位
sum=0
for i in {1..17}; do
num=${idcard17:i-1:1}
weight=$((2**(18-i)%11))
if [[ $num == "X" || $num == "x" ]]; then
num=10
fi
sum=$((sum + num * weight))
done
check=$((12 - sum % 11))
if [[ $check == 10 ]]; then
check="X"
fi
# 比对校验位
if [[ ${idcard: -1} == $check ]]; then
echo "身份证校验位号码合法"
else
echo "身份证号码校验位不正确"
fi
fi
else
echo "身份证号码不合法"
fi
done
```