Python 身份证校验代码

Python 身份证校验代码

居民身份证bai编号识别   1、身份证编码规则如下:根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。   地址码(身份证前六位)表示编码对象第一次申领居民身份证时的常住户口所在县(市、旗、区)的行政区划代码。(所有区域的编码可以到网站查询到最新的县及县以上的行政编码资料。)   生日期码(身份证第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。   顺序码(身份证第十五位到十七位)是县、区级政府所辖派出所的分配码,每个派出所分配码为10个连续号码,例如“000-009”或“060-069”,其中单数为男性分配码,双数为女性分配码,如遇同年同月同日有两人以上时顺延第二、第三、第四、第五个分配码。如:007的就是个男生,而且和他同年月日生的男生至少有两个,他们的后四位是001和003。分配顺序码中“999、998、997、996”四个顺序号分别为男女性百岁以上老人专用的特定编号。   校验码(身份证最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码。   2、从1999年10月1日起,全国实行公民身份证号码制度,居民身份证编号由原15位升至18位。前6位为地址码;第七位至14位为出生日期码,此码由6位数改为8位数,其中年份用4位数表示;第15位至17位为顺序码,取消了顺序码中对百岁老人使用的特定编号;第十八位为校验码,主要是为了校验计算机输入公民身份证号码的前17位数字是否正确,其取值范围是0至10,当值等于10时,用罗马数字符χ表示。   三、身份证第18位(校验码)的计算方法   1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。   2、将这17位数字和系数相乘的结果相加。   3、用加出来和除以11,看余数是多少?   4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。   5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。   例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。   首先我们得出前17位的乘积和是189,然后用189除以11得出的结果是17+2/11,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的数字是x。所以,可以判定这是一个合格的身份证号码。

import re

def checkIdcard(idcard):
    Errors = ['验证通过!', '身份证号码位数不对!', '身份证号码出生日期超出范围或含有非法字符!', '身份证号码校验错误!', '身份证地区非法!']
    area = {"11": "北京", "12": "天津", "13": "河北", "14": "山西", "15": "内蒙古", "21": "辽宁", "22": "吉林", "23": "黑龙江",
            "31": "上海",
            "32": "江苏", "33": "浙江", "34": "安徽", "35": "福建", "36": "江西", "37": "山东", "41": "河南", "42": "湖北", "43": "湖南",
            "44": "广东", "45": "广西", "46": "海南", "50": "重庆", "51": "四川", "52": "贵州", "53": "云南", "54": "西藏", "61": "陕西",
            "62": "甘肃", "63": "青海", "64": "宁夏", "65": "新疆", "71": "台湾", "81": "香港", "82": "澳门", "91": "国外"}
    idcard = str(idcard)
    idcard = idcard.strip()
    idcard_list = list(idcard)

    # 地区校验
    key = idcard[0: 2]  # TODO: cc  地区中的键是否存在
    if key in area.keys():
        if (not area[(idcard)[0:2]]):
            return Errors[4]
    else:
        return Errors[4]
    # 15位身份号码检测

    if (len(idcard) == 15):
        if ((int(idcard[6:8]) + 1900) % 4 == 0 or (
                (int(idcard[6:8]) + 1900) % 100 == 0 and (int(idcard[6:8]) + 1900) % 4 == 0)):
            ereg = re.compile(
                '[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$')  # //测试出生日期的合法性
        else:
            ereg = re.compile(
                '[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$')  # //测试出生日期的合法性
        if (re.match(ereg, idcard)):
            return Errors[0]
        else:
            return Errors[2]
    # 18位身份号码检测
    elif (len(idcard) == 18):
        # 出生日期的合法性检查
        # 闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))
        # 平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))
        if (int(idcard[6:10]) % 4 == 0 or (int(idcard[6:10]) % 100 == 0 and int(idcard[6:10]) % 4 == 0)):
            ereg = re.compile(
                '[1-9][0-9]{5}(19[0-9]{2}|20[0-9]{2})((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$')  # //闰年出生日期的合法性正则表达式
        else:
            ereg = re.compile(
                '[1-9][0-9]{5}(19[0-9]{2}|20[0-9]{2})((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$')  # //平年出生日期的合法性正则表达式
        # //测试出生日期的合法性
        if (re.match(ereg, idcard)):
            # //计算校验位
            S = (int(idcard_list[0]) + int(idcard_list[10])) * 7 + (int(idcard_list[1]) + int(idcard_list[11])) * 9 + (
                        int(
                            idcard_list[2]) + int(idcard_list[12])) * 10 + (
                            int(idcard_list[3]) + int(idcard_list[13])) * 5 + (int(
                idcard_list[4]) + int(idcard_list[14])) * 8 + (int(idcard_list[5]) + int(idcard_list[15])) * 4 + (int(
                idcard_list[6]) + int(idcard_list[16])) * 2 + int(idcard_list[7]) * 1 + int(idcard_list[8]) * 6 + int(
                idcard_list[9]) * 3
            Y = S % 11
            M = "F"
            JYM = "10X98765432"
            M = JYM[Y]  # 判断校验位
            if idcard_list[17] in ['X', 'x']:
                idcard_list[17] = 'X'
            if (M == idcard_list[17]):  # 检测ID的校验位
                return Errors[0]
            else:
                return Errors[3]
        else:
            return Errors[2]
    else:
        return Errors[1]

转载: https://blog.csdn.net/baidu_39416074/article/details/80927445

posted @ 2021-01-15 11:36  adrian-boy  阅读(1699)  评论(0编辑  收藏  举报