7-3 查驗身份證
分數 10
作者 陳越
單位 浙江大學
一個合法的身份證號碼由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<iostream>
#include<string>
#include<string.h>
using namespace std;
int isCorrect(char a[20])
{
char M = a[17]; //校驗位
//將字元轉化為對應數字,並計算加權和sum,以及題目中的z
int num[20];
int weight[20] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
int sum = 0;
for (int i = 0; i < 17; i++)
{
num[i] = a[i] - '0'; //ASCLL碼
sum += num[i] * weight[i]; //易錯:這裡沒說要除以總權重
}
int z = sum % 11;
//確定z對應的正確的校驗位judge
char judge;
switch (z)
{
case 0:
judge = '1';
break;
case 1:
judge = '0';
break;
case 2:
judge = 'X';
break;
case 3:
judge = '9';
break;
case 4:
judge = '8';
break;
case 5:
judge = '7';
break;
case 6:
judge = '6';
break;
case 7:
judge = '5';
break;
case 8:
judge = '4';
break;
case 9:
judge = '3';
break;
case 10:
judge = '2';
break;
default:
break;
}
//比較judge和M
if (judge == M)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int isAllPassed = 1; //等於1說明全部正確,等於0說明不完全正確
//輸入N,迴圈N次
int N;
cin >> N;
for (int i = 0; i < N; i++)
{
//以字元陣列形式,輸入前17位數,檢查是否全是整數
char str[20];
int isInt = 1;
for (int j = 0; j < 17; j++)
{
cin >> str[j];
if (str[j] < 48 || str[j]>57) //檢查前17位是否全是整數
{
isInt = 0; //前17位不全為整數
isAllPassed = 0;
}
}
//如果前17位不全為整數,有問題,輸出號碼
if (isInt == 0)
{
cin >> str[17];
str[18] = '\0';
cout << str << endl;
}
else //前17位全為整數,正確,接著檢查校驗碼是否準確
{
cin >> str[17];
str[18] = '\0';
if (isCorrect(str) == 0) //呼叫isCorrect函式,檢查校驗碼,如果正確返回1,錯誤返回0
{
cout << str << endl;
isAllPassed = 0;
}
}
}
if (isAllPassed) //如果全部正常,輸出All passed
cout << "All passed" << endl;
return 0;
}