描述
中国目前采用的是18位身份证号,其第7-10位数字是出生年,11-12位是出生月份,13-14是出生日期,第17位是性别,奇数为男性,偶数为女性,第18位是校验位。 如果身份证号码的其中一位填错了(包括最后一个校验位),则校验算法可以检测出来。如果身份证号的相邻2位填反了,则校验算法可以检测出来。校验规则如下:
用户输入一个身份证号,校验其是否是合法的身份证号码:
输入格式
一个18位身份证号,末位为数字或大写字母X
输出格式
如身份证号码不合法输出 '身份证校验错误', 如身份证号码合法则分别在3行中输出'身份证号码校验为合法号码'以及该人的出生年月日和性别。(月份和日期均为2位数表示)
---------------------------------------------------------------------------------------------------------------------------------
下面是我的写的代码
import datetime
def checklen(id): #检查长度是否为18位
if len(id) != 18:
return False
return True
def check(id):
lst = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
s = sum(lst[i] * int(id[i]) for i in range(17))
checklst = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
if str(checklst[s % 11]) != id[17]:
return False
else:
if int(id[6:10]) > datetime.datetime.now().year or int(id[10:12]) < 1 or int(id[10:12]) > 12 or int(id[12:14]) < 1 or int(id[12:14]) > 31:
return False
mlst = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if int(id[6:10]) % 400 or (int(id[6:10]) % 4 == 0 and int(id[6:10]) % 100 != 0):
mlst[1] = 29
if int(id[12:14]) > mlst[int(id[10:12]) - 1]:
return False
return True
def gender(id): #性别判定
if int(id[16]) in [1, 3, 5, 7, 9]:
return '男'
elif int(id[16]) in [2, 4, 6, 8]:
return '女'
def out(id): #输出设定
print('身份证号码校验为合法号码')
print('出生:{}月{}月{}日'.format(id[6:10], id[10:12], id[12:14]))
print('性别:'+str(gender(id)))
if __name__ == '__main__':
id = input()
if checklen(id) == True and check(id) == True:
out(id)
else:
print('身份证校验错误')
输入自己的身份证号和家人的都可以得出结果,但是给到用例中就出现了报错。
下面是例题给出的代码
import datetime # 导入datetime模块用于获取当年年份
def leap(year):
return True if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0) else False
# 校验身证号中的年月日及校验码
def check_date(id_num):
"""校验身证号中的年月日,年月日值均要合法"""
# 年份超过当前年,或月份小于1或大于12,或日期小于1或大于31时非法
if int(id_num[6:10]) > datetime.datetime.now().year or int(id_num[10:12]) < 1 or int(id_num[10:12]) > 12 or int(
id_num[12:14]) < 1 or int(id_num[12:14]) > 31:
return False
if int(id_num[10:12]) in [4, 6, 9, 11] and int(id_num[12:14]) > 30: # 当月份为4,6,9,11时,日期超过30即非法
return False
if int(id_num[10:12]) == 2 and int(id_num[12:14]) > 29: # 月份为2时,日期大于29便非法
return False
if int(id_num[10:12]) == 2 and leap(int(id_num[6:10])) == False and int(
id_num[12:14]) > 28: # 月份为2时,如果不是闰年,日期大于28便非法
return False
else:
return True
def check_sum(id_num):
"""计算检验位"""
ls = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
id_num_sum = sum([ls[i] * int(id_num[i]) for i in range(17)]) # 计算校验和
if id_num[17] == 'X':
return True if id_num_sum % 11 == 2 else False
elif (id_num_sum % 11 + int(id_num[17])) % 11 == 1:
return True
else:
return False
def print_info(id_num):
"""输出信息"""
year = int(id_num[6:10])
month = id_num[10:12]
day = id_num[12:14]
if len(id_num) == 18 and check_date(id_num) and check_sum(id_num): # 先判断长度是否是18位,再判断校验和
gender = '女' if int(id_num[16]) % 2 == 0 else '男'
print('身份证号码校验为合法号码')
print('出生:{}年{}月{}日'.format(year, month, day))
# print('年龄:{}'.format(datetime.datetime.now().year - year))
print('性别:{}'.format(gender))
else:
print('身份证校验错误')
if __name__ == '__main__':
id_number = input()
print_info(id_number)
还在看我哪里错了……