中华人民共和国公民身份证一共有18位数,由六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码组成。 其中第十七位奇数分给男性,偶数分给女性,身份证最后一位是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码,其取值范围是0至10,当值等于10时,用罗马数字符X表示。
有些游戏厂商是没有权力接入国家公安系统数据库的,但是有时我们输入错误的身份证号时会提示出错,感觉好像真能识别身份证信息一样。其实游戏厂商只是校验了最后一位数是否符合ISO7064:1983.MOD11-2校验码而已。
下面说一下ISO7064:1983.MOD11-2校验码的具体算法步骤:
假如我们的身份证前17位数是 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7,
-
对前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位数字与对应的加权因子的乘机和sum:1×7 + 2×9 + 3×10 + 4×5 + 5×8 + 6×4 + 7×2 + 8×1 + 9×6 + 0×3 + 1×7 + 2×9 + 3×10 + 4×5 + 5×8 + 6×4 + 7×2 = 368 -
加权运算的和对11取余数:
368 % 11 = 5; -
12减去余数的差继续对11取余数,得到最后的校验码:
(12 - 5)%11 = 7;校验码是7
这18位身份证号应该是:1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 7
注意:如果最后的校验码如果是10,需要用字母’X’替换。
下满分享一下具体的实现代码:
#include <iostream>
using namespace std;
int weight[17] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
int main()
{
int sum = 0;
int remainder, crc;
int id[17] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7};
char idCard[18] = { 0 };
for (int idx = 0; idx < 17; idx++){
sum += weight[idx] * id[idx]; //计算加权和
idCard[idx] = id[idx] + 48; //将int型数字转化为char字符保存,ascii码字符0-9对应十进制48-57
}
remainder = sum % 11;
crc = (12 - remainder) % 11;
/*身份证最后一位如果是10,用X替换*/
idCard[17] = (crc != 10) ? (crc + 48) : 88; //ascii码字符X对应十进制88
cout<<"your id is:"<<endl;
for (int idx = 0; idx < 18; idx++){
cout << idCard[idx] << " ";
}
cout << endl;
return 0;
}
结果显示: