【风控数据】 身份证件数据及验证
简述
随着实名制的不断推进, 越来越多的网站和应用都会让用户填写身份证件等信息, 该类数据一般均为风控数据最为基准的数据内容, 该类信息除利用公安库接口进行比对, 还有一些前端可实现的方法进行一定的逻辑判断.
校验位匹配
大陆身份证
大陆身份证号由18位数字构成, 共分为四个部分:
1-6
: 6位数字地区码7-14
: 8位数字出身年月码15-17
: 3位数字顺序码18
: 1位校验码
假设17位数字是
17位数字 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
加权因子 | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
- 计算17位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{17} w_i n_i\)
- 计算其的余数: \(T = S mod 11\)
- 计算余数 \(R = (12 - T) mod 11}\),
如果 \(R = 10\) 则校验位为字母
X
否则为数字R
#include<bits/stdc++.h>
int weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 通过映射减少第三步运算
string checkMap = "10X98765432";
bool isChinaId(string idCard) {
if(idCard.length() != 18) return false;
int checkBit = 0;
for (int i = 0; i < 17; ++i) {
if (idCard[i] < '0' || idCard[i] > '9') return false;
checkBit += (idCard[i] - '0') * weights[i];
}
return idCard[17] == checkMap[checkBit % 11];
}
香港身份证
香港身份证号码共有8位, 由三部分组成:
1
: 1位英文字母2-7
: 6位数字8
: 1位校验码计算9位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{7} (9 - i) n_i\)
- 其中第一位字母转化为
1-26
- 其中第一位字母转化为
计算其的余数: \(T = S mod 11\)
- \(T = 0\):
校验码
0
- \(T = 1\):
校验码
A
- \(2 <= T <= 10\):
校验码
11 - T
- \(T = 0\):
校验码
#include<bits/stdc++.h>
bool isChinaId(string idCard) {
if(idCard.length() != 8 || idCard[0] < 'A' || idCard[0] > 'Z') return false;
int checkBit = (idCard[0] - 'A') * 8;
for (int i = 1; i < 7; ++i) {
if (idCard[i] < '0' || idCard[i] > '9') return false;
checkBit += (idCard[i] - '0') * (8 - i);
}
checkBit = checkBit % 11;
if (checkBit == 0 && idCard[7] == '0') {
return true;
} else if (checkBit == 1 && idCard[7] == 'A') {
return true;
} else if(idCard[7] == 11 - checkBit + '0'){
return true;
}
return false;
}
台湾身份证
台湾身份证号码共10位, 第1位是字母, 后面9位是数字.
1
: 字母代表地区分别以A-Z表示;2
: 数字代表性别, 男性是1, 女性是23-9
: 任意的一串数字10
: 校验码计算9位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{9} (10 - i) n_i\)
计算其的余数: \(T = S mod 10\)
计算余数 \(R = (10 - T) mod 10}\), 即为校验位
#include<bits/stdc++.h>
bool isChinaId(string idCard) {
if(idCard.length() != 10 || idCard[0] < 'A' || idCard[0] > 'Z') return false;
int checkBit = (idCard[0] - 'A') / 10 + (idCard[0] - 'A') % 10 * 9;
for (int i = 1; i < 9; ++i) {
if (idCard[i] < '0' || idCard[i] > '9') return false;
checkBit += (idCard[i] - '0') * (9 - i);
}
checkBit = (10 - checkBit % 10) % 10;
return idCard[9] == '0' + checkBit;
}
参考资料
【风控数据】 身份证件数据及验证
https://www.windism.cn/1255115666.html