|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 hynet1024 于 2022-11-8 20:39 编辑
在日常应用中,经常需要输入身份证号,因为号码较长容易录错,因此需要进行实时校验,以尽可能保证输入正确。以下以Python为例,浅聊身份证号码校验的方法。
首先我们需要了解身份证号各个号段的意义。身份证号共18位,其中前6位是行政区划编码,7--14位是出生日期(格式为xxxx年xx月xx日),15--17位是顺序编码(其中第17位是性别编码,奇数代表男,偶数代表女),最后第18位则是校验码。前17位都是数字,最后一位校验码共11个,分别是0,1,2,3,4,5,6,7,8,9,Ⅹ(不是字母X,是罗马数字的10,也可以当做数字理解)。
校验码是如何生成的呢?是根据前17位进行系数运算得来的。
系数运算又是怎么回事呢?其实很简单,请记住10个系数和他们的循环顺序,依次是:7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2。按这个顺序分别与身份证前17位对应相乘,再将每个乘积相加得到一个累加值,最后将这个累计值除以11,得到一个余数(可能是0,1,2,3,4,5,6,7,8,9,10的其中一个),将这个余数按顺序与1,0,X,9,8,7,6,5,4,3,2对应即为校验码。
如果你还有点晕,那么看看下面的实例就会明白了。
如有身份证号为:42058219721014003?(这里先隐去校验码),共17位,将第1位4乘以7得到28,第2位2乘以9得到18,第3位0乘以10得到0,.....第17位3乘以2得到6,将17个乘积相加,各个乘积累加值为245。见图1
将累加值除以11,余数为3,按图2对应表得知,余数3对应的校验码为9,因此该身份码末位校验码就是9,即完整的身份证号为420582197210140039。
好了,基本理论弄明白了,下面来分析下代码该做些什么。其实代码很低简单,只是要考虑的问题多一点,整理如下:
1、身份证长度必须为18位长,前17位必须为数字(最后一位如果是X,也可以当做数字处理,为方便本例只处理前17位)
2、出生日期必须是合法的日历格式(包括判断是否闰年)
3、出生年份应介于1900年--当前年份之间(含)
4、出生日期不能晚于当天
5、检查校验码是否正确
若以上规则校验通过,则提示身份证号校验无误,并根据第17位判断出性别予以提示。
好了,最后直接上代码。本人也是初学者,出于兴趣聊做此文,在代码上未能做到尽善尽美,欢迎点评完善,期待各位高人指点。
import time
import datetime
#系数:
coeff = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
#检验码
check = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
while True:
ID = input('请输入身份证号:')
if ID != 'Q':
if len(ID) == 18: #身份证号长度是否为18位
if ID[0:17].isdigit(): #前17位是否为数字
id17 = list(map(int, list(ID[0:17]))) #将前17位转换为数字列表
if int(ID[6:10]) in range(1900, int(datetime.datetime.now().strftime('%Y')) + 1): #判断出生年份是否在1900~当前年份之间
if int(ID[6:14]) <= int(datetime.datetime.now().strftime("%Y%m%d")): #判断出生日期是否晚于当前日期
try:
time.strptime(ID[6:14], "%Y%m%d") #判断出生日期是否为合法的日期
mod = sum(list(map(lambda x, y : x * y, id17, coeff))) % 11 #将身份证间17位与系数相乘后累加,最后阶以11,得到余数
if str(check[mod]) == ID[-1]: #判断余数与对应的校验码是否匹配
print(f'\t***身份证号校验无误,性别为[{"女" if int(ID[-2]) % 2 == 0 else "男"}]***')
else:
print(f'\t身份证末位校验码不正确(应为[{check[mod]}])')
except:
print(f'\t出生日期[{ID[6:10]}年{ID[10:12]}月{ID[12:14]}日]不是合法的日期')
else:
print(f'\t出生日期[{ID[6:14]}]不应晚于当前日期[{datetime.datetime.now().strftime("%Y%m%d")}]')
else:
print(f'\t出生年份{ID[6:10]}错误,应介于[1900--{datetime.datetime.now().strftime("%Y")}]年之间')
else:
print('\t身份证前17位应全部为数字')
else:
print('\t身份证长度应为18位')
else:
print('谢谢使用,再见!')
break
print()
|
-
-
|