身份證有效性校驗

請寫程式碼校驗第二代身份證號碼有效性。程式接收一個18位的身份證號碼和性別,根據以下規則輸出號碼是有效還是無效。 

 

第二代身份證號組成規則: 

a) 身份證號碼(18位)= 地址碼(6)+ 出生日期碼(8)+ 順序碼(3)+校驗碼(1); 

b) 地址碼:保證位數合法即可,無需校驗合法性; 

c) 出生日期碼:格式為YYYYMMDD,需校驗日期有效性; 

d) 順序碼:男性為奇數,女性為偶數; 

e) 校驗碼: 

  S = ∑(i = 1, 17) { A[i] * W[i] } 

  Y = S % 11 

  校驗碼 N = (12 – Y) % 11 

所以N取值範圍是0-10,10在身份證號碼中用大寫字母’X’表示 

  i:表示號碼字元從右至左包括校驗碼字元在內的位置序號 

  A[i]:表示第i位置上的身份證號碼字元值 

  W[i]:表示第i位置上的加權係數,其數列為7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 

輸入

110101199003071938 Male

輸出

Pass
 
def isTrueDate(a):
    """查詢輸入日期是否有效"""
    # 把年月日剝離出來
    year = int(a[0:4])
    month = int(a[4:6])
    day = int(a[6:])
    # 判斷月份是否不在0-12的範圍內
    if month == 0 | month > 12:
        return False
    # 如果 一三五七八十臘 那麼 三十一天永不差
    else:
        if month == 1 | month == 3 | month == 5 | month == 7 | month == 8 | month == 10 | month == 12:
            if day > 31:
                return False
        # 四六九冬三十天
        else:
            if month == 4 | month == 6 | month == 9 | month == 11 :
                if day > 30:
                    return False
            # 平年二月二十八,但如果年份是400的倍數,二月還是二十九天
            else:
                if year % 400 != 0 & year % 4 == 0:
                    if day > 28:
                        return False
                else:
                    if day > 29:
                        return False
    return True

def check(a):
    if not a.isdigit():
        return False

    else:
        # 調用isTRUEDate方法
        if isTrueDate(a):
            return True
        else:
            return False

def jiaoyan(num):
    result = None
    b = num[:-1]
    c = num[-1]
    lst = ('0','1','2','3','4','5','6','7','8','9','X')
    xishu = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)
    S = sum([int(b[i])*xishu[i] for i in range(17)])
    Y = S % 11
    N = (12 - Y) % 11

    if N == 10:
        result = 'X'
    else:
        result = str(N)
    if result in lst and result == c:
        return True
    else:
        return False


line = input().strip().split()
while True:
    num = line[0]
    sex = line[1]
    if len(num) != 18 or not num[0:6].isdigit():
        break
    else:
        if check(num[6:14]) and int(num[14:17]) % 2 == 0 and jiaoyan(num) and sex == 'Female':
            print("Pass")
        elif check(num[6:14]) and int(num[14:17]) % 2 == 1 and jiaoyan(num) and sex == 'Male':
            print("Pass")
        else:
            print("Fail")
    line = input().strip().split()

  

Tags: