天天看點

驗證身份證的合規性

'''
身份證的判定規則

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】輸入的身份證長度不對!")