身份证校验码(最后一位)是根据前面十七位数字码,按照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('\n校验和 | 余数 | 查表校验字符--->', 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 << "\t= " << (ai * wi) << endl;
sigma += (ai * wi);
}
int number = sigma % 11;
cout << w[number] << " ---->\t " << 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] = '\0';
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'};