关于身份证号的那些事

转自:http://www.biaodianfu.com/id-number.html?f=http://blogread.cn/

居民身份证号码,根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由17位数字本体码和1位数字校验码组成。排列顺序从左至右依次为:6位数字地址码、8位数字出生日期码、3位数字顺序码和1位数字校验码。
关于身份证号的那些事_第1张图片

一、身份证号码的组成

1、地址码(身份证号码前6位)

表示编码对象常住户口所在县(市、镇、区)的行政区划代码。
1-2位:省、自治区、直辖市代码;
3-4位:地级市、盟、自治州代码;
5-6位:县、县级市、区代码。

2、出生日期码(身份证号码第7位到第14位)

表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。

3、顺序码(身份证号码第15位到17位)

地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第17位奇数分给男性,偶数分给女性。

4、校验码(身份证号码最后一位)

是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替。

二、身份证校验码计算方法

  • 1、将前面的身份证号码17位数分别乘以不同的系数。从第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。通过上面得知如果余数是2,身份证的最后一位号码就是罗马数字x。如果余数是10,就会在身份证的第18位数字上出现的是2。

三、身份证校验Python版

import re
from datetime import datetime

__all__ = ["GeneratIdentityChecker"]

class ExceptionIdentityChecker(Exception):
    pass

def GeneratIdentityChecker(country = "China"):
    cls = globals().get(country+"IdentityChecker")
    if cls:
        return cls()
    else:
        raise ExceptionIdentityChecker(country+" identity's checker not found")

class ChinaIdentityChecker():
    def __init__(self):
        self.anWi = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)
        self.cnAreaPart = 6
        self.cnMod = 11
        self.csYearPre = "19"
        self.csCheckCode = "10X98765432"
        self.cnMinArea = 150000
        self.cnMaxArea = 700000
    def check(self,code,**options):
        code = code.upper()
        if len(code) not in (15,18) or not re.match(r"^\d{15}$|^\d{17}[\dxX]$", code):
            return False
        area = int(code[0:self.cnAreaPart])
        if not (self.cnMinArea <= area <= self.cnMaxArea):
            return False
        birthday = self.csYearPre+code[6:12] if len(code) == 15 else code[6:14]
        try:
            datetime.strptime(birthday, "%Y%M%d")
        except:
            return False
        if len(code) == 18:
            wi = self.anWi
            total = 0
            for i in range(16,-1,-1):
                total += int(code[i])*wi[i]
            if not self.csCheckCode[total%self.cnMod] == code[17]:
                    return False
        for i in options:
            try:
                checker = getattr(self,"_check_"+i)
            except:
                return False
            if not checker(code,options[i]):
                return False
        return True

    def _check_sex(self,code,sex):
        sex_flag = code[14] if len(code) == 15 else code[16]
        sex = sex.upper()
        if sex == "M":
            return int(sex_flag)%2 == 1
        elif sex == "F":
            return int(sex_flag)%2 == 0
        else:
            return False

if __name__ == "__main__":
    gic = GeneratIdentityChecker()
    print gic.check("34052419800101001X")

你可能感兴趣的:(身份证号的秘密)