zoukankan      html  css  js  c++  java
  • 使用 python 进行身份证号校验

    使用 python 代码进行身份证号校验

    先说,还有很多可以优化的地方。
    1、比如加入15位身份证号的校验,嗯哼,15位的好像没有校验,那就只能提取个出生年月日啥的了。
    2、比如判断加入地址数据库,增加输出信息
    3、增加时间判断,出生日期大于当前时间的判为非法

    代码是老师放了一个提取出生年月日的题目扩展过来的,目前来看代码运行正常,有没有bug就不造了。

    身份证号校验规则

    话说身份证号校验,最重要的肯定是校验。那么如何校验?如何又有15、18位身份证号之分?

    1、1999年07月01日以前使用15位身份证号,也就是第一代身份证
    2、二代身份证增加位数至18,多出来的3位分别是出生年份的前两个数字和一位校验码
    3、身份证各位置代表信息如下
    身份证校验
    4、顺序码的前两位代表当地派出所代码,第三位是对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
    5、校验码,身份证号18位,前17位为本体码,最后一位是算出来的校验码。校验规则如下:

    前17位分别乘以【7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2】
    然后将17个乘积加一块取余11得到一个0-10范围的数字
    0-10分别对应【1,0,x,9,8,7,6,5,4,3,2】即校验位数字
    出现 x 是因为校验码为10但为了保证号码长度不变,换成了 x

    python校验身份证号代码如下:

    version1.1

    def check_id_length(n):
        if len(str(n)) != 18:
            print("只支持18位身份证号查询")
            return False
        else:
            return True
    def check_id_data(n):
            var=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
            var_id=['1','0','x','9','8','7','6','5','4','3','2']
            n = str(n)
            sum = 0
            if int(n[16])%2==0:
                gender="女"
                same=int(int(n[16])/2)
            else:
                gender="男"
                same=int((int(n[16])+1)/2)
            for i in range(0,17):
                sum += int(n[i])*var[i]
            sum %= 11
            if (var_id[sum])==str(n[17]):
                print("身份证号规则核验通过,校验码是:",var_id[sum])
                print("出生于:",n[6:10],"年",n[10:12],"月",n[12:14],"日","性别:",gender,"
    当地同性别同生日排名:",same)
                return sum
            else:
                print("出生于:",n[6:10],"年",n[10:12],"月",n[12:14],"日","性别:",gender,"
    当地同性别同生日排名:",same)
                print("但身份证号规则核验失败,校验码应为",var_id[sum],",当前校验码是:",n[17])
                return 0
    n = input("请输入18位身份证号:")
    if check_id_length(n):
        check_id_data(n)
    else:
        print("请重新输入")
                           
    

    代码说明

    1、前六行定义了长度校验函数,校验长度是否为 18
    2、7-28行定义了校验位验证函数,验证校验位是否正确
    3、29-33行调用了上述两行数以完成校验功能

    其中
    1、第8行定义了加权数字列表,列表元素类型为 int
    2、第9行定义了标准校验位列表,列表元素类型为 str
    3、第10行将接收到的身份证号转换为 str 类型,以方便切片提出中间位
    4、12-17行用于计算身份证号主性别以及当地(派出所管辖范围)同性别同生日人的顺序
    5、18-20分别进行了加权求和并取余, 这是也是这段小代码的核心算法
    6、21-28进行校验位对比,并输出对比结果,同时提出出生年月日

    演示代码,加入显示判断

    verion1.2

    import time
    def check_id_length(n):
        if len(str(n)) != 18:
            print("只支持18位身份证号查询")
            return False
        else:
            return True
    
    def check_id_data(n):
        n = str(n)
        n2 = str(n[:16])
        time_now = int(time.strftime("%Y",time.localtime()))
        is_digit = (not(n2.isdigit())) or (not(n[17].isdigit()) and (n[17]) !="x")
        if (is_digit):
            print("对不起,您这是火星身份证,暂不受理")
        elif (int(n[6:10]))>time_now:
                print(n[6:10],"年的人?您是穿越回来吗?")
        elif (int(n[10:12]))>12:
            print(n[10:12],"月出生?,您是捡来的吧!!")
        elif (int(n[12:14]))>31:
            print(n[12:14],"日出生?,您一定是充话费送的")
        else:
            check_id_data2(n)
    def check_id_data2(n):
            var=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
            var_id=['1','0','x','9','8','7','6','5','4','3','2']
            sum = 0
            if int(n[16])%2==0:
                gender="女"
                same=int(int(n[16])/2)
            else:
                gender="男"
                same=int((int(n[16])+1)/2)
            for i in range(0,17):
                sum += int(n[i])*var[i]
            sum %= 11
            if (var_id[sum])==str(n[17]):
                print("身份证号规则核验通过,校验码是:",var_id[sum])
                print("出生于:",n[6:10],"年",n[10:12],"月",n[12:14],"日","性别:",gender,"
    当地同性别同生日排名:",same)
                return sum
            else:
                print("出生于:",n[6:10],"年",n[10:12],"月",n[12:14],"日","性别:",gender,"
    当地同性别同生日排名:",same)
                print("但身份证号规则核验失败,校验码应为",var_id[sum],",当前校验码是:",n[17])
                return 0
    while(1):
        print("
    菜单,请输入数字
    ----------------------")
        print("输入1手动输入身份证号")
        print("输入2选择测试号")
        print("不然就拜拜")
        print("----------------------")
        select = input("
    请输入:")
        if (select.isdigit()):
            pass
        else:
            print("说好的输入数字的呢,拜拜了您嘞")
            break
        select = int(select)
        if (select == 1):
            n = input("请输入18位身份证号:")
            if check_id_length(n):
                check_id_data(n)
            else:
                print("请重新输入")
        elif select == 2:
                     print("
    ----------------------")
                     print("开始校验身份证号:61011519920317602")
                     check_id_length(61011519920317602)
                     print("
    ----------------------")
                     print("开始校验身份证号:610115199203176021")
                     check_id_data(610115199203176021)
                     print("
    ----------------------")
                     print("开始校验身份证号:610115199203176028")
                     check_id_data(610115199203176028)
        else:
                     break
    
    

    代码测试效果如下:
    测试图一
    测试图二:

    测试图二
    测试图三:

    测试图三

    更多测试请自行运行代码!

  • 相关阅读:
    Zookeeper基本使用(转)
    mongon命令(转)
    openstack之cinder
    raw格式转换成qcow2格式
    calico网络
    route命令使用
    guestfish修改镜像内容
    基于etcd插件的CoreDNS动态域名添加
    dns记录类型(转)
    C语言 格式化输出--%m.n
  • 原文地址:https://www.cnblogs.com/amnotgcs/p/12694395.html
Copyright © 2011-2022 走看看