【风控数据】 身份证件数据及验证

简述

随着实名制的不断推进, 越来越多的网站和应用都会让用户填写身份证件等信息, 该类数据一般均为风控数据最为基准的数据内容, 该类信息除利用公安库接口进行比对, 还有一些前端可实现的方法进行一定的逻辑判断.

校验位匹配

大陆身份证

大陆身份证号由18位数字构成, 共分为四个部分:

  1. 1-6: 6位数字地区码
  2. 7-14: 8位数字出身年月码
  3. 15-17: 3位数字顺序码
  4. 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
  1. 计算17位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{17} w_i n_i\)
  2. 计算其的余数: \(T = S mod 11\)
  3. 计算余数 \(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: 1位英文字母

  2. 2-7: 6位数字

  3. 8: 1位校验码

  4. 计算9位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{7} (9 - i) n_i\)

    • 其中第一位字母转化为 1-26
  5. 计算其的余数: \(T = S mod 11\)

    • \(T = 0\): 校验码0
    • \(T = 1\): 校验码A
    • \(2 <= T <= 10\): 校验码11 - T
#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. 1: 字母代表地区分别以A-Z表示;

  2. 2: 数字代表性别, 男性是1, 女性是2

  3. 3-9: 任意的一串数字

  4. 10: 校验码

  5. 计算9位数字各位数字与对应的加权因子的乘积: \(S = \sum_{i = 1}^{9} (10 - i) n_i\)

  6. 计算其的余数: \(T = S mod 10\)

  7. 计算余数 \(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;
}

参考资料

  1. 校验码

【风控数据】 身份证件数据及验证
https://www.windism.cn/1255115666.html
作者
windism
发布于
2022年2月17日
许可协议