'''
身份證的判定規則
1.1.1 位址碼規則:
位址碼長6位
以數字1-9開頭
1.1.2 年份碼規則:
年份碼長4位
以數字18,19或20開頭
1.1.3 月份碼規則:
月份碼長2位,介于01-12之間
1.1.4 日期碼規則:
日期碼長2位,介于01-31之間
根據前位月份不同,後位日期有不同建制條件
閏年2月29天,平年2月28天(閏年:能被4整除但不能被100整除的年份為普通閏年)
大月31天(1,3,5,7,8,10,12)
小月30天(2,4,6,9,11)
1.1.5 順序碼規則:
順序碼長3位的數字,通過它可以判定性别
1.1.6 校驗碼規則:
校驗碼長1位
可以是數字,字母x或字母X
'''
# 身份證合規驗證
while True:
my_text = input('請輸入待驗證的身份證号碼:')
my_text=my_text.strip() # 去除字元串兩端無意輸入的空格
my_bol = True
if len(my_text) == 18: # 總長度判定
if my_text[:17].isnumeric(): # 前17位是否均為數字的判定
if my_text[:1]=='0': # 首位數字不能為0的判定
print('【NG】區域碼首位數字不能為0 !')
else:
if my_text[6:8] in ['18','19','20']: # 年份合理性判定
if int(my_text[10:12]) >= 1 and int(my_text[10:12]) <= 12: # 月份合理性判定
if int(my_text[12:14]) >= 1 and int(my_text[12:14]) <= 31: # 日期合理性判定
if int(my_text[10:12]) in [4,6,9,11]: # 小月相關判定(除2月)
if int(my_text[12:14]) == 31:
my_bol=False
print('【NG】小月不存在31日 !')
elif int(my_text[10:12]) == 2 and int(my_text[12:14]) == 29: # 針對不同年份的2月29日進行判定
if int(my_text[6:10]) % 4 != 0: # 如果年份不能整除4,為平年
my_bol=False
elif int(my_text[6:10]) % 100 == 0:
if int(my_text[6:10]) % 400 != 0: # 如果年份能整除4,且能整除100,但不能整除400時為平年
my_bol = False
if my_bol == False:
print('【NG】平年2月不存在29日 !')
if my_text[-1].isnumeric() or my_text[-1].upper() == 'X': # 最後一位要麼是數字,要麼是大小寫x
if my_bol:
print('【 --OK-- 】該身份證編碼合規!出生日期:', my_text[6:10], '年', my_text[10:12], '月',
my_text[12:14], '日 性别:', '女' if int(my_text[16]) % 2 == 0 else '男')
else:
print('【NG】最後一位校驗碼不對!')
else:
print('【NG】身份證日期不在合理範圍!')
else:
print('【NG】身份證月份超出合理範圍!')
else:
print('【NG】身份證年份超出合理範圍!')
else:
print('【NG】待驗證的字元串前17位不全是數字,非法!')
elif my_text=='q':
break
else:
print("【NG】輸入的身份證長度不對!")