Python学习记录Day5——身份证有效性校验

题目描述

请写代码校验第二代身份证号码有效性。程序接收一个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

idnum,sex=input().split()
b=list(idnum)

date = b[6:14]

year = date[0:4]
year1 = int(''.join(year))
month = date[4:6]
month1 = int(''.join(month))
day = date[6:8]
day1 = int(''.join(day))

sexnum = b[14:17]
sexnum1 = int(''.join(sexnum))

a=b[0:17]
a1=list(map(int,a))
w1=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
s=0
for i in range(0,17):
    s+=a1[i]*w1[i]
y=s%11
n=(12-y)%11  
if n==10:
    n1='X'
else:
    n1=str(n)
monthlist1=[31,28,31,30,31,30,31,31,30,31,30,31]
monthlist2=[31,29,31,30,31,30,31,31,30,31,30,31]
if year1%4 == 0 and year1%100 != 0 or year1%400 == 0:
    monthlist=monthlist2
else:
    monthlist=monthlist1
if len(idnum)==18 and (sex=='Female'or sex=='Male'):
    if year1>=0 and year1<=2020 and month1>= 1 and month1 <= 12:
        if day1>=1 and day1<= monthlist[month1-1]:
            if n1==b[17]:
                if (sexnum1 %2==0 and sex=='Female')or(sexnum1%2!=0 and sex=='Male'):
                    print('Pass')
                else:
                    print('Fail')
            else:
                print('Fail')
        else:
           print('Fail')
    else:
        print('Fail')
else:
    print('Fail')
身份证校验通常指的是验证一个中国大陆的居民身份证号码是否符合官方规定的格式以及是否真实有效。在Python中,我们可以通过编写函数来实现这样的校验。 中国大陆的居民身份证号码为18位,其中前17位是数字,最后一位可能是数字或者大写字母X。身份证号码的构成遵循以下规则: 1. 前6位是地区代码。 2. 接下来的8位是出生日期码(年年年年月月日日)。 3. 紧接着的3位是顺序码,奇数分配给男性,偶数分配给女性。 4. 最后一位是校验码,用于检验身份证号码的正确性。 校验码的计算方法如下: - 将前17位数字分别乘以不同的系数。从第一位到第十七位的系数分别是:7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2。 - 将这17位数字和系数相乘后的结果相加。 - 将相加后的和除以11,得到余数。 - 根据余数,通过查表得到最后一位校验码。 以下是一个简单的Python函数,用于校验18位身份证号码是否有效: ```python def check_id_card(id_card): # 校验码对应值 check_code_dict = { 0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2' } # 地区码 area_code = id_card[:6] # 出生日期码 birth_date_code = id_card[6:14] # 顺序码 sequence_code = id_card[14:17] # 校验码 check_code = id_card[17] # 检查长度 if len(id_card) != 18: return False # 检查地区码是否全部为数字 if not area_code.isdigit(): return False # 检查出生日期码是否符合日期格式 try: year = int(birth_date_code[:4]) month = int(birth_date_code[4:6]) day = int(birth_date_code[6:8]) datetime.date(year, month, day) except ValueError: return False # 检查顺序码是否全部为数字 if not sequence_code.isdigit(): return False # 计算校验码 sum_of_coefficients = sum(int(a) * b for a, b in zip(id_card[:-1], range(17, 0, -1))) remainder = sum_of_coefficients % 11 if check_code != check_code_dict[remainder]: return False # 所有校验通过 return True ``` 需要注意的是,上述代码只提供了基本的格式校验,并没有对地区代码的有效性进行检验,也没有对出生日期的合理性(如是否为闰年)进行校验。在实际应用中,可能需要结合更多的规则和数据进行完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值