身份证校验码(最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码。
第十八位为校验码,主要是为了校验计算机输入公民身份证号码的前17位数字是否正确,其取值范围是0至10,当值等于10时,用罗马数字符X表示。

python 学习测试版本

# 身份证 最后一位校验位
sigma = 0
a = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
w = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']

cnid = '34052419800101001X'

for i in range(17):
    n = ord(cnid[i]) - ord('0')
    print(n,  end=' ')
    sigma += n * a[i]

x = sigma % 11
print('
校验和 |  余数 | 查表校验字符--->', sigma , 'mod 11 =' , x,  w[x])
#  校验和 |  余数 | 查表校验字符---> 189 mod 11 = 2 X

计算方法

1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2、将这17位数字和系数相乘的结果相加。
3、用加出来和除以11,看余数是多少?
4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X...)
5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。

C++ 版本

#include <iostream>
#include <string.h>
using namespace std;

char cnid18crc(const char *id18);  // 身份证 最后一位校验位
void cnid_15to18(char *id18 , const char *id15);   // 身份证 15位升级18位

int main()
{
    char cnid15[19] = "340524800101001";
    char cnid18[19] ;
    cnid_15to18(cnid18, cnid15);

    cout << cnid15 << endl;
    cout << cnid18 << endl;
    return 0;
}

// 身份证 最后一位校验位
char cnid18crc(const char *id18)
{
    int sigma = 0;
    int a[]  = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    char w[] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    for (int i = 0; i < 17; i++) {
        int ai =  id18[i] - '0';
        int wi = a[i];
        cout << ai <<  " * " << wi << "    = " << (ai * wi) << endl;
        sigma += (ai * wi);
    }
    int number = sigma % 11;
    cout << w[number] << " ---->     " << sigma << " mod 11 = " << number << endl ;

    return w[number];
}

// 身份证 15位升级18位
void cnid_15to18(char *id18 , const char *id15)
{
    char *ps = id18 + 2;
    strcpy(ps , id15);
    strncpy(id18 , id15 , 6);
    id18[6] = '1';
    id18[7] = '9';
    id18[17] = 'C';
    id18[18] = '';

    id18[17] = cnid18crc(id18);

}
3 * 7   = 21
4 * 9   = 36
0 * 10  = 0
5 * 5   = 25
2 * 8   = 16
4 * 4   = 16
1 * 2   = 2
9 * 1   = 9
8 * 6   = 48
0 * 3   = 0
0 * 7   = 0
1 * 9   = 9
0 * 10  = 0
1 * 5   = 5
0 * 8   = 0
0 * 4   = 0
1 * 2   = 2
X ---->  189 mod 11 = 2
340524800101001
34052419800101001X
// 运行结果,加权因子,校验码表
int a[]  = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
char w[] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

MOD11-2.png


0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注