秦春娣 黄晓伟
【摘要】 C语言程序设计作为高职计算机专业学生的基础语言,在整个课程中的相当重要的。学习C语言程序设计不仅能让学生了解基本的程序设计概念,还能让学生学会使用编程语言的代码结构,更能让学生学会编程的思想。为后续学习其他语言:如JAVA、Python等语言打下扎实的基础。传统的C语言学习都是通过语法学习,加上小的案例来讲解的,缺乏对实际生活中案例的整体框架编程设计。针对上述情况,下面将通过生活实际案例,应用C语言程序设计判断身份证号校验码项目进行教学案例分析。
【关键词】 身份证号 校验码 项目化教学
引言:
C语言从上个世纪70年代诞生至今将近50年,它仍旧活跃在信息技术的各个领域。在信息技术发展日新月异的今天,一项技术生存了50年仍保青春,不得不说,C语言是一种功能强大,生命力强的程序设计语言。如此功能强大的结构化的程序设计语言,有着丰富的数据类型,有着基本的语言结构,有着顺序结构、选择结构、循环结构的基本技能。传统的C语言程序设计教学是采用小程序设计为案例的,它如何与面向对象的程序设计语言衔接呢?我们的课程采用项目化教学就非常有必要了。
一、案例背景
在项目化教学案例的设计过程中,如果缺少与实际生活相关的例子,学生在学习过程中就会缺少学习的动力。那么老师在设计“C语言程序设计”项目化案例时,根据日常生活实际问题具体情景进行项目设计。
本案例我们应用C语言程序设计对身份证号校验码验证的项目来分析,通过对18位身份证号码的组成原理,校验码的检验真伪算法及实现身份证号校验码的项目设计来讲解。
二、身份证号码有关知识
2.1身份證号的组成
公民身份证号码是按照一定的规则组成的,它由十七位数字和一位校验码构成。从左至右一到六位数字是地址码,七至十四数字是出生日期码,十五至十七数字是顺序码,最后一位为校验码。十八位数字我们可以用字母来表示:ABCDEFYYYYMMDDXXXR。
1、地址码(ABCDEF):表示常住户口所在省、市、区的行政代码。比如:340000表示安徽省;340100 表示安徽省合肥市;340101 表示安徽省合肥市市辖区。
2、出生日期码(YYYYMMDD):表示该人员的出生年月日,比如:2020年1月11日出生的人员,出生日期码为:20200111,月份和日期不足两位的,我们在前面加0,数字之间是不用分隔符的。
3、顺序码(XXX):表示是对身份证号前六位相同(同一个地区内),又是同年同月同日出生的人员编定的顺序码,奇数代表是男性,偶数代表是女性,可以更好的区别男女。
4、校验码(R):根据前面17位数字,按照校验码计算方法得出一位数。
2.2校验码的计算方式
1、根据前面17位数字进行加权求和:公式:S=Sum(Ai*Wi),i=1至17,其中Ai为第i位置上身份证号码数字值,Wi为第i位置上的加权因子,相应的17位加权因子:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2。
身份证号码上每一位数字与相应的加权因子相乘的积相加,计算出总和S。
2、用11对计算结果取模 Y=mod(S,11) ,S除以11,看得到的余数。余数Y有0至10共11个数字。
3、按照模的值对应的校验码如下图:
2.3校验码出现‘X
根据上表的对应关系,我们发现校验码有11个,如果我们用数字0到9来表示,就缺少一位。用二位数字来表示的话,身份证号就变成19位了。因为Ⅹ代青罗马数字的10,所以这里用X来代替其中一位校验码。这样可以保障公民身份证号符合国家标准。
三、项目设计
3.1开发环境
开发语言:C语言
开发工具:Code::Blocks/Dev-C++
3.2项目需求
输入身份证号码,以字符串的形式放入字符数组中,调用判断身份证号号码函数,首先判断位数是否为18位,接着判断除最后一位可以是大写X或小写x以外,其他位必须是数字,满足以上二个条件后,再来判断最后一位校验位是否正确。如果以上条件都能满足,那么我们就判断身份证号码是合法的,否则为不合法。
3.3数据类型
本案例中,我们将应用到了int char long的数据类型,加权因子采用整型数组,校验码和身份证号码都采用字符数组的类型。
3.4涉及的知识点
本程序用到C语言基础知识,所涉及到的知识点如下:
(1)stdio.h、string.h和ctype.h头文件的引入;
(2)用户自定义函数及函数的调用;
(3)数组的定义和初始化,缺省数组的大小时,必须初始化数据,编译器会自动计算数据的大小。如:int R[] ={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; //加权因子;
(4)调用字符串长度函数strlen(),计算字符长度;调用数字判断isdigit()函数;
(5)字符转换为数值功能,如0-48=0 字符‘0变成数值0;
(6)gets()可以接受带有空格的字符,而scanf()函数遇到空格就截断,我们要理解两者之间的区别;
(7)%,取模运算就是自然数学中的求余数,参与取模运算的两个操作数都是整型数。
四、项目编码
4.1核心算法分析
函数是完成某个特定功能的模块代码。通过调用模块代码完成某项功能。我们定义了一个身份证验证函数,用来检测输入的字符串身份证号码的有效性。最后一位校验码是根据前面 17 位数字码,按照 ISO 7064:1983.MOD 11-2 校验码计算出来的校验码。
我们采用用户自定义函数Chk18PaperId函数来完成身份证号校验过程。
在Chk18PaperId函数中我们首先对字符串身份证码进行位数的判断,如果字符串长度不等于18位,那么我们直接返回,判定该身份证号码为不合法。在字符串长度为18位的基础上,我们再来判断每一位是否是数字字符或者最后一位是罗马数字X,这里为了方便,我们直接用英文字母X来表示。满足以上两个条件之后,我们再来判断最后一位校验码是否正确。
假设某一身份证号前17位:
17位数字 3 2 0 6 2 1 1 9 9 5 0 7 1 8 3 0 2
加权因子 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
根据加权求和公式S = Sum(Ai * Wi),计算17位数字各位数字与对应的加权因子的乘积的和S:3×7+2×9+0×10+6×5+2×8+1×4+1×2+9×1+9×6+5×3+0×7+7×9+1×10+8×5+3×8+0×4+2×2=310;
计算S÷11的余数T:310 % 11=2;余数0-10对应校验码为[1, 0, X , 9, 8, 7, 6, 5, 4, 3, 2],
那么该身份证号码的第18位校验码就是X。
4.2完整代码
#include
#include
#include
int Chk18PaperId (const char *sPaperId) //函数用来判断身份证号校验码是否合法
{ long lSumQT =0;
int R[] ={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; //加权因子
char sChecker[11]={'1','0','X', '9', '8', '7', '6', '5', '4', '3', '2'}; //校验码
if( 18 != strlen(sPaperId)) return -1; //检验长度
int i=0; //校验数字
for (i=0; i<18; i++)
{ if ( !isdigit(sPaperId[i]) && !(('X' == sPaperId[i] || 'x' == sPaperId[i])&& 17 == i) )
{ return -1;//如果身份证号码中某一位不是数字或者X 的话,则返回-1,失败}}
for (i=0; i<=16; i++)//验证最末的校验码
{ lSumQT += (sPaperId[i]-48) * R[i];}
if (sChecker[lSumQT%11] != sPaperId[17] )
{ return -1;}
return 0; }
int main(void)
{ char Personal_ID[18];
printf("请输入一个身份证号码:\n");
gets(Personal_ID); //用户输入一个字符串身份证号码
if(!Chk18PaperId(Personal_ID)) printf("合法\n"); //调用自定义校验码函数
else printf("不合法\n");
return 0;}
五、结论
C语言本身提供了强大的算法功能,而且还提供项目实践功能。我们对C语言程序设计进行项目化教学,在教学案例设计中根据高职学生学习的特点,设计出符合学生的C语言项目教学案例,从而提高学生学习C语言解决各种实际问题的能力。
参 考 文 献
[1]许芝卉,李建华.关于C语言程序设计题自动评分算法的探究,山西大同大学报,2020(10).
[2]唐小健.探究C语言程序设计在项目实践中的技巧应用,电脑编程技术与维护,2020(11).
[3]周军强.C 语言程序设计课程项目化教学研究,福建电脑,2020(04).
[4]俞骋.项目教学法在技校C语言教学中的实证研究,现代计算机,2019(14).
[5]林剑.C语言程序设计课程教学探索,課程教育研究,2019(02).
秦春娣(1981-),女,江苏常州人,实验师,工程师,本科,主要研究方向为计算机应用;
黄晓伟(1981-),男,江苏常州人,副教授,研究方向:工业自动化控制。