一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前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
现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
输入格式:
输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。
输出格式:
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出All passed
。
输入样例1:
4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X
输出样例1:
12010X198901011234
110108196711301866
37070419881216001X
输入样例2:
2
320124198808240056
110108196711301862
输出样例2:
All passed
鸣谢阜阳师范学院范建中老师补充数据
鸣谢浙江工业大学之江学院石洗凡老师纠正数据
#include<stdio.h>
#define size 21
int Weight(char num[size])
{ int t;t=(num[0]-'0')*7+(num[1]-'0')*9+(num[2]-'0')*10+(num[3]-'0')*5+(num[4]-'0')*8+(num[5]-'0')*4+(num[6]-'0')*2+(num[7]-'0')*1+(num[8]-'0')*6+(num[9]-'0')*3+(num[10]-'0')*7+(num[11]-'0')*9+(num[12]-'0')*10+(num[13]-'0')*5+(num[14]-'0')*8+(num[15]-'0')*4+(num[16]-'0')*2;t=t%11;return t;
}
char Check(int n)
{char s;switch(n){case 0 :s='1';break;case 1 :s='0';break;case 2 :s='X';break;case 3 :s='9';break;case 4 :s='8';break;case 5 :s='7';break;case 6 :s='6';break;case 7 :s='5';break;case 8 :s='4';break;case 9 :s='3';break;case 10:s='2';break;}return s;
}
int main()
{int i,j,N,error=0;char date[100][size]={'\0'};scanf("%d",&N);for(i=0;i<N;i++){scanf("%s",date[i]);for(j=0;j<17;j++){if(date[i][j]<'0'||date[i][j]>'9') {date[i][size-1]=1; break;}}if(date[i][17]!=Check(Weight(date[i]))) {date[i][size-1]=1;}}for(i=0;i<N;i++){if(date[i][size-1]){printf("%s\n",date[i]);error++;}}if(!error) {printf("All passed\n");}return 0;
}
这段代码是一个C程序,它检查输入的一组日期字符串是否符合特定的格式和校验规则。下面是对代码的逐行解释:
-
#include<stdio.h>
: 引入标准输入输出库。 -
#define size 21
: 定义一个预处理器宏,将size
替换为21。 -
int Weight(char num[size])
: 定义一个函数Weight
,它接受一个长度为21的字符数组作为参数,并返回一个整数。这个函数计算给定字符串的“重量”(实际上是一个校验和)。- 函数内部,使用字符数组中的每个字符(数字字符)减去字符'0',将其转换为整数。然后,根据一个特定的算法(看起来像是某种校验和的计算),将这些整数相加。
- 结果取模11,得到一个介于0和10之间的值。
-
char Check(int n)
: 定义一个函数Check
,它接受一个整数作为参数,并返回一个字符。这个函数将整数参数转换为对应的字符。 -
int main()
: 主函数开始。 -
int i,j,N,error=0;
: 声明一些整数变量。 -
char date[100][size]={'\0'};
: 声明一个二维字符数组date
,用于存储日期字符串。每个字符串长度为21,并初始化为空字符。 -
scanf("%d",&N);
: 从标准输入读取一个整数,存储在变量N
中,表示要检查的日期字符串的数量。 -
for(i=0;i<N;i++)
: 外循环,遍历每个日期字符串。 -
scanf("%s",date[i]);
: 读取一个日期字符串,并存储在date[i]
中。 -
内循环(由
for(j=0;j<17;j++)
控制)检查日期字符串中的每个字符:- 如果字符不是数字(即小于'0'或大于'9'),则将
date[i][size-1]
设置为1,表示该字符串无效。
- 如果字符不是数字(即小于'0'或大于'9'),则将
-
if(date[i][17]!=Check(Weight(date[i])))
: 检查计算出的校验和是否与日期字符串的第18个字符匹配。如果不匹配,将date[i][size-1]
设置为1,表示该字符串无效。 -
for(i=0;i<N;i++)
: 再次遍历每个日期字符串。 -
if(date[i][size-1])
: 如果日期字符串的最后一个字符为1(表示无效),则输出该字符串。同时,error
计数器增加。 -
if(!error)
: 如果在所有日期字符串中都没有发现无效的字符串,则输出"All passed"。 -
return 0;
: 主函数返回0,表示程序正常结束。
这个程序主要的功能是检查输入的日期字符串是否符合特定的格式和校验规则。如果某个日期字符串不符合规则,程序会输出该字符串;如果所有日期字符串都符合规则,程序会输出"All passed"。