纯C语言打造身份证检验系统,让你一波秀翻你身边的朋友!

闲来无事,想不想秀翻身边队友呢?

闲来无事昨天在逛B站的时候,突然看到有个同样在深究C语言的朋友发了一个关于身份证检验系统的视频,因此就静下来看了一下,从学习到分析,将其构成一定的思路自己补充完全前前后后花费了将近3个小时,可能也是因为自己还是不够熟练的原因的,但是好歹算是将其整体的完成了,看到成果的时候还是挺让人高兴的。

开发一个程序之前,最为重要的是它所涉及到的每个步骤

所说到的每个步骤,笼统一些的说法其实就是所构建的它所要满足的条件,比如对于身份证检验系统来说,不仅要满足年月日,还应该满足最后一位的ISO校验,也就是因为这一系列的问题才会导致很多的朋友难以快速的完成对于程序的需求,因此很难快速的完成对一个程序的补充和完善。

程序段

主函数段

如果大家读懂了主函数,或者说是知道要检验一个身份证所需要检验那些东西,那么编写一个身份证检验系统绝对是分分钟就可以完成的了。

//**核心主函数** 
int main()
{
	char id[20] = { 0 };//定义所需要输入身份证的长度
	char choose;//为之后查询结束一个之后是否结束程序做准备
	int year, month, day;
	printf("※Luckily原创小程序※\n身份证号校验or查询系统\n");
start:
	printf("————————————\n");
	printf("请输入需要查询的身份证号:\n");
	scanf("%18s", id);
	if (CheckFormat(id) == 0) goto start;//基础格式的检查,是用来检查身份证是否为18位
	year = Trans(id[6]) * 1000 + Trans(id[7]) * 100 + Trans(id[8]) * 10 + Trans(id[9]);
	month = Trans(id[10]) * 10 + Trans(id[11]);//进行年月日的转换,从身份证之中转换出来我们所需要计算的年月日
	day = Trans(id[12]) * 10 + Trans(id[13]);
	if (CheckData(year, month, day) == 0)goto start;//检查年月日是否符合正规的日期
	if (CheckCode(id) == 0) goto start;//身份证最后一位ISO的校验
	printf("该身份证号是合法的身份证号!\n");
	printf("————————————\n");
	printf("信息如下:\n");
	FindAddress(id);//输出身份证前六位所对应的地理位置
	FindSex(id);//输出性别
	FindBirthday(year, month, day);//出生日期
	FindCode(id);//所在当地是同年同月里第多少个孩子
	printf("————————————\n");
	printf("是否要再次查询?按Y继续,按其他键退出。\n");
	choose = _getch();
	if (choose == 'Y' || choose == 'y')goto start;
	system("pause");
	return 0;
}

子函数段

  1. ------字符转数字的函数-------
int Trans(char c)
{
	return (c - 48);
}
//因为我们所输入进去的都是ASCII值,而要完成查需转换为具体的数字
//数字字符值减去48才能够得到所对应的整型数值
  1. ------基础格式检查函数-------
int CheckFormat(char *id)  //用来检查所输入的身份证号的长度是否为18
{
	if (strlen(id) != 18)
	{
		printf("输入错误,长度不正确,请检查后重试!\n");
		return 0;
	}
	for (i = 0; i < 17; i++)//检查所输入的第1-17位是否为数组
	{
		if (id[i]>'9' || id[i] < '0')
		{
			printf("输入错误,第1-17位出现非数字,请检查后重试!\n");
			return 0;
		}
	}
	if ((id[17]>'9' || id[17] < '0')&&id[17] != 'X')//检查所输入的第十八位是否为数字或者是X
	{
		printf("输入错误,第18位不是数字或X,请检查后重试!\n");
		return 0;
	}
	return 1;
}

  1. ------出生日期检查函数-------
int CheckData(int year, int month, int day)//用来检查输入的身份证号第7-14位出生日期的格式是否正确
{
	int sign = 1;
	if (month > 12 || month < 1) sign = 0;//检查所输入的月份是否正确
	if (month == 2)//如果2月的话,则判断此年份是否是闰年
	{
		if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		{
			if (day>29 || day < 1)sign = 0;
		}
		else if (day>28 || day < 1)sign = 0;
	}
	switch (month)//根据月份来判断月份天数是否合格
	{//此都归为大月
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		if (day > 31 || day < 1)sign = 0; break;
	case 4://此类归为小月
	case 6:
	case 9:
	case 11:
		if (day > 30 || day < 1)sign = 0; break;
	}
	if (sign == 0)
	{
		printf("该身份证号出生日期格式不正确,请检查后重试!\n");
		return 0;
	}
	return 1;
}

  1. ------ISO效验码检查函数-------
int CheckCode(char *id)
{//对于这一个子函数的定义,很多人可能会不懂,我们可以进行百度搜索关于身份证校验的规则就可以明白
	int r[17] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
	int check;
	char code[11] = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3','2'};
	int sum = 0;
	for (i = 0; i < 17; i++)
	{
		sum += (Trans(id[i]))*r[i];
	}
	check = sum % 11;
	if (id[17] != code[check])
	{
		printf("该身份证号未通过ISO校验,请检查最后一位后重试\n");
		return 0;
	}

	return 1;
}

  1. ------常住户口所在地输出函数-------
void FindAddress(char *id)//根据身份证前六位输出所对应的地址
{
	int address;
	address = Trans(id[0]) * 100000 + Trans(id[1]) * 10000
		+ Trans(id[2]) * 1000 + Trans(id[3]) * 100
		+ Trans(id[4]) * 10 + Trans(id[5]);
	printf("常住户口所在地:");
	DataBase(address);//调用基础数据检测前六位所对应的地址
	printf("\n");
}

  1. ------性别输出函数-------
//身份证的第17位,奇数为男,偶数为女,通过除2得余数来判断
void FindSex(char *id)
{
	int sex = Trans(id[16]);
	printf("性别:");
	if (sex % 2 == 1)printf("男\n");
	if (sex % 2 == 0)printf("女\n");
}
  1. ------年龄和出生日期输出函数-------
void FindBirthday(int year,int month,int day)//用来计算身份证所对应的出生年月日来计算对应的年龄
{
	time_t timep;
	struct tm *p;
	time(&timep);
	p = gmtime(&timep);//获取系统时间中的年份
	printf("年龄:%d岁\n", (1900 + p->tm_year) - year);
	printf("出生日期:%4d年%2d月%2d日\n",year,month,day);
}

  1. ------顺序码输出函数-------
void FindCode(char *id)//表示给同地同日出生的人进行编号第15-17位原样输出即可
{
	printf("当地同年同月同日出生的第%c%c%c个孩子\n", id[14], id[15], id[16]);
}
  1. ------行政区划代码数据库-------
void DataBase(int address)
{
	switch (address)
	{
	case 110000:printf("北京市"); break;
	case 110100:printf("北京市市辖区"); break;
	case 110101:printf("北京市市辖区东城区"); break;
	case 110102:printf("北京市市辖区西城区"); break;
	...
	...
	...
	case 710000:printf("台湾省"); break;
	case 810000:printf("香港特别行政区"); break;
	case 820000:printf("澳门特别行政区"); break;
	default:
		printf("数据库中无此行政代码"); break;
	}
}

因为所对应的地点太多,因此我完整的程序大家可以在我的GitHub上取,我会将链接附在后面,并且将行政区划代码数据文件也粘贴在后面,可以供大家使用,代码就这些, 快做出来自己过过瘾吧。
身份证校验系统GitHub链接
我所整理出来的数据是excel格式的,但是博客上所需要上传都是扩展名必须包含.md,所以我将其以压缩包的形式放在了资源之中了,大家可以下载免费使用了。

发布了18 篇原创文章 · 获赞 12 · 访问量 954

猜你喜欢

转载自blog.csdn.net/Luckily0818/article/details/103979005