查驗身份證(c語言)
阿新 • • 發佈:2019-02-19
一個合法的身份證號碼由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])//自定義函式算加權值Z,考慮到身份證可能含字母,用字元陣列儲存身份證,故而形參也是字元陣列
{
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; //'數字'-'0'=數字,也可能出現前17位誤入字母的情況,這個時候就是'字元'-'0'= ASCII碼差值(數字字元也是這樣,只不過正好是需要的值)
}
char Check(int n) //自定義函式算加權結果對應的效驗碼M,函式返回值也是字元型,與身份證(字元型)最後一位比較
{
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') //如果出現前17位誤入字母的情況,直接退出第一個迴圈(第一個身份證)
{
date[i][size-1]=1; //輸入的身份證沒有佔完size,利用(size-1)位置標記正確和錯誤
break;
}
}
if(date[i][17]!=Check(Weight(date[i]))) //比較身份證第18位是否等於效驗碼M
{
date[i][size-1]=1;
}
}
for(i=0;i<N;i++)
{
if(date[i][size-1])
{
printf("%s\n",date[i]);
error++;
}
}
if(!error) //當error==0時,說明沒有出現問題
{
printf("All passed\n");
}
return 0;
}