'''
身份证的判定规则
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】输入的身份证长度不对!")