seansie's blog

zerojudge a020. 身分證檢驗 詳解

題目連結 a020. 身分證檢驗

//	AC (2ms, 116KB)
#include <stdio.h>
int main() {
    char city, num[10]; /*!身分證字號的數字雖然是整數型態,
                          但因為輸入的時候各數字間沒有空格,整個數列會被視為一個整數,
                          因此需用字元陣列偵測並儲存輸入*/
                        /*因為整數型態所佔的記憶體空間比字元大,可確保資料型態的轉換過程中不會有資料遺失,
                          因此字元型態的變數在遇到需要用整數型態判別或運算的時候,會自動轉為整數。
                          嚴謹的寫法是 : (轉換後的的資料型態)變數名稱... e.g. (int)city... */
    scanf("%c%s", &city, num);
    if(city>=65 && city<=72) 
        city-=55;
    else if(city=='I')
        city-=39;
    else if(city>=74 && city<=78)
        city-=56;
    else if(city=='O')
        city-=44;
    else if(city>=80 && city<=86)
        city-=57;
    else if(city=='W')
        city-=55;
    else if(city=='X' || city=='Y')
        city-=58;
    else if(city=='Z')
        city-=57;

    int sum=num[8]-48;
    for(int i=0;i<8;i++) /*!身分證字號數字共9碼,除去最後一碼共8碼,i值最大為7*/
        sum+=(num[i]-48)*(8-i);
    sum+=city/10+(city%10)*9;

    if(sum%10==0)
        printf("real");
    else
        printf("fake");

    return 0;
}

程式碼分析

char city, num[10]; /*!身分證字號的數字雖然是整數型態,
                          但因為輸入的時候各數字間沒有空格,整個數列會被視為一個整數,
                          因此需用字元陣列偵測並儲存輸入*/

這段程式碼宣告了兩個變數:

  • city:用於儲存身分證字號的第一個英文字母
  • num:用於儲存身分證字號的九個數字

英文代號轉換

if(city>=65 && city<=72) 
    city-=55;
else if(city=='I')
    city-=39;
else if(city>=74 && city<=78)
        city-=56;
else if(city=='O')
    city-=44;
else if(city>=80 && city<=86)
    city-=57;
else if(city=='W')
    city-=55;
else if(city=='X' || city=='Y')
    city-=58;
else if(city=='Z')
    city-=57;

這段程式碼將身分證字號的第一個英文字母轉換為一個數字,其規則如下:

  • A 到 I,將其 ASCII 代碼減去 55
  • I,將其 ASCII 代碼減去 39
  • J 到 O,將其 ASCII 代碼減去 56
  • O,將其 ASCII 代碼減去 44
  • P 到 W,將其 ASCII 代碼減去 57
  • W,將其 ASCII 代碼減去 55
  • X 和 Y,將其 ASCII 代碼減去 58
  • Z,將其 ASCII 代碼減去 57

計算檢查碼

int sum=num[8]-48;
for(int i=0;i<8;i++) /*!身分證字號數字共9碼,除去最後一碼共8碼,i值最大為7*/
    sum+=(num[i]-48)*(8-i);
sum+=city/10+(city%10)*9;

這段程式碼計算身分證字號的檢查碼,其步驟如下:

  1. 將最後一碼轉換為數字
  2. 將前八個數字乘以各自的權數(8 到 1),並將乘積相加
  3. 將轉換後的英文字母的十位數和個位數分別乘以 9 和 1,並將結果相加
  4. 將上述三項結果相加

判斷是否符合規則

if(sum%10==0)
    printf("real");
else
    printf("fake");

這段程式碼判斷計算出的檢查碼是否為 0。如果為 0,則表示輸入的身分證字號符合規則;否則不符合。

程式範例

以下是程式範例:

Input: T112663836
Output: real

Input: S154287863
Output: fake

由以上程式碼正確地實現了中華民國身分證字號檢查規則。