身份证校验码计算:根据身份证前17位计算第18位校验码-c++实现

1.身份证号码的组成

公民身份证号码共18位,由十七位数字码和一位校验码组成。第18位校验码是由前17位计算得出的。

1-2位:省份代码
3-4位:城市代码
5-6位:区县(旗)代码
7-14位:出生日期
15-16位:顺序编码,由该辖区派出所指定,00-99
17位:性别,奇数代表男性,偶数代表女性
18位:校验码,由前17位计算得出


2.第18位校验码的计算规则:

首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},然后将计算的和对11取模得到值Z,按照以下关系对应Z值与校验码M的值

Z 0 1 2 3 4 5 6 7 8 9 10
M 1 0 X 9 8 7 6 5 4 3 2

编写程序:输入有效身份证号的前17位,计算第18位校验码。

c++代码如下:

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

int main()
{
	char t[] = { '1','0','X','9','8','7','6','5','4','3','2' };
	string s = "";
	cout << "请输入身份证前17位:" ;
	
	while (1) {
		cin >> s;

		if (s.length() != 17) {
			s.clear();
			cout << "输入有误,请重新输入:";
		}
		else {
			break;
		}
	}
	
	int j = ((s[0] - '0') * 7 + (s[1] - '0') * 9 + (s[2] - '0') * 10 + (s[3] - '0') * 5 + (s[4] - '0') * 8 + (s[5] - '0') * 4 + \
		(s[6] - '0') * 2 + (s[7] - '0') * 1 + (s[8] - '0') * 6 + (s[9] - '0') * 3 + (s[10] - '0') * 7 + (s[11] - '0') * 9 + \
		(s[12] - '0') * 10 + (s[13] - '0') * 5 + (s[14] - '0') * 8 + (s[15] - '0') * 4 + (s[16] - '0') * 2) % 11;
	cout <<"第18位校验码为:" <<t[j] << endl;
	return 0;
}

程序运行结果:

3.身份证号码会重复吗?

通过上面的介绍,我们发现,对同一个县区的人来说,身份证号唯一性由身份证号码的15-17位这三位决定,同时,17位表示性别的各有五个数字。三位数字最多可以表示1000个(000-999),其中男性和女性各一半500个。

所以结论是:同一个县区同一天出生的同一性别的人数超过500个,身份证号才会有重复。那500是个什么概念呢?

根据国家统计局发布的《中华人民共和国2019年国民经济和社会发展统计公报》,2019年我国新生儿数量是1,465万,我国有县级行政区2862个,所以大致可以算一下平均每天每个县区的新生人口为:1465万/2862/365 ≈14。这还是不区分性别的,即便这样,这个数字离500还有很大的差距,所以实际上身份证号码基本是不可能重复的,只存在理论上的可能。

猜你喜欢

转载自blog.csdn.net/weixin_44843859/article/details/112232937