hynet1024 发表于 2022-11-8 20:20:39

使用Python进行身份证输入校验

本帖最后由 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 =
#检验码
check =

while True:
    ID = input('请输入身份证号:')
    if ID != 'Q':
      if len(ID) == 18:        #身份证号长度是否为18位
            if ID.isdigit():        #前17位是否为数字
                id17 = list(map(int, list(ID)))        #将前17位转换为数字列表
                if int(ID) in range(1900, int(datetime.datetime.now().strftime('%Y')) + 1):        #判断出生年份是否在1900~当前年份之间
                  if int(ID) <= int(datetime.datetime.now().strftime("%Y%m%d")):        #判断出生日期是否晚于当前日期
                        try:
                            time.strptime(ID, "%Y%m%d")        #判断出生日期是否为合法的日期
                            mod = sum(list(map(lambda x, y : x * y, id17, coeff))) % 11        #将身份证间17位与系数相乘后累加,最后阶以11,得到余数
                            if str(check) == ID[-1]:                #判断余数与对应的校验码是否匹配
                              print(f'\t***身份证号校验无误,性别为[{"女" if int(ID[-2]) % 2 == 0 else "男"}]***')
                            else:
                              print(f'\t身份证末位校验码不正确(应为[{check}])')                     
                        except:
                            print(f'\t出生日期[{ID}年{ID}月{ID}日]不是合法的日期')
                  else:
                        print(f'\t出生日期[{ID}]不应晚于当前日期[{datetime.datetime.now().strftime("%Y%m%d")}]')
                else:
                  print(f'\t出生年份{ID}错误,应介于年之间')
            else:
                print('\t身份证前17位应全部为数字')
      else:
            print('\t身份证长度应为18位')
    else:
      print('谢谢使用,再见!')
      break
    print()


页: [1]
查看完整版本: 使用Python进行身份证输入校验