身份证最后一位校验算法

中华人民共和国公民身份证一共有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,

  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位数字与对应的加权因子的乘机和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

  2. 加权运算的和对11取余数:
    368 % 11 = 5;

  3. 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;
}

结果显示:
在这里插入图片描述

注:ASCII码表连接跳转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生命如歌,代码如诗

听说,打赏我的人都找到了真爱!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值