IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

关于身份证号的那些事

标点符 2013-01-08 13:35:47 累计浏览 5,507 次
本机暂存

居民身份证号码,根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

原图已失效

一、身份证号码的组成

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

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

关于行政区划代码具体的对应关系,可以从国家统计局网站上直接获取。

具体地址为:http://www.stats.gov.cn/tjbz/xzqhdm/

2、生日期码(身份证号码第七位到第十四位)

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

3、顺序码(身份证号码第十五位到十七位)

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

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

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

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

#-*- coding:UTF-8 -*-
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")

同分类推荐文章

  1. 对基本有序的序列排序算法 (2026-06-11 17:46:49)
  2. Four Levels Of Customer Understanding (2026-05-22 21:00:00)
  3. 除法的意义 (2026-04-12 20:52:17)

查看更多 算法 文章 →

建议继续学习

  1. 如何成为Python高手 (累计阅读 54,992)
  2. 天朝第二代身份证号码的验证机制 (累计阅读 14,761)
  3. 规范自己的JavaScript书写 (累计阅读 7,089)
  4. PHP编码规范 (累计阅读 5,618)
  5. 为什么编码规范里要求每行代码不超过80个字符的限制是合理的 (累计阅读 4,841)
  6. 编码规范集锦 (累计阅读 3,827)
  7. 如何编写高质量的Javascript代码 (累计阅读 3,752)
  8. 编码风格不是编码规范 (累计阅读 3,659)
  9. 用PHP计算身份证校验码 (累计阅读 3,244)
  10. php的filter扩展小技巧 (累计阅读 3,106)