請寫代碼校驗第二代身份證號碼有效性。程序接收一個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()