Python实现身份证号码解析


Posted in Python onSeptember 01, 2015

中国的居民身份证有18位。其中前17位是信息码,最后1位是校验码。每位信息码可以是0-9的数字,而校验码可以是0-9或X,其中X表示10。

身份证校验码算法:

设18位身份证号序列从左到右为:
引用
a[0], a[1], a[2], a[3], ..., a[16], a[17]

其中a[i]表示第i位数字,i=0,1,2,...,17,如果最后一位(校验位)是X,则a[17]=10

每一位被赋予一个“权值”,其中,第i位的权值w[i]的计算方法是:
引用
w[i] = 2**(17-i) % 11

其中,i=0,1,2,3,...,17,运算符按Python惯例:x**y表示x的y次方,x%y表示x除以y的余数。

如果一个身份证号是正确的,那么:
引用
(a[0]*w[0] + a[1]*w[1] + a[2]*w[2] + ... + a[16]*w[16] + a[17]*w[17]) % 11 == 1

实际上,校验位a[17]的计算方法,就是巧妙地选择一个值使得上式成立。

根据上述算法,下面是一个验证身份证号正确性的程序。

初学者————代码没有什么依照编写规范,流水账的模式。还有两个功能没有实现:
1、依照身份证号码的区域代码解析所在区域;
2、将身份证校验码的校验作为前置判断,如果错误就不再解析其他内容,汗,我还不会;

ID=input('请输入十八位身份证号码: ')
if len(ID)==18:
  print("你的身份证号码是 "+ID)
else:
  print("错误的身份证号码")
 
ID_add=ID[0:6]
ID_birth=ID[6:14]
ID_sex=ID[14:17]
ID_check=ID[17]
 
#ID_add是身份证中的区域代码,如果有一个行政区划代码字典,就可以用获取大致地址#
 
year=ID_birth[0:4]
moon=ID_birth[4:6]
day=ID_birth[6:8]
print("生日: "+year+'年'+moon+'月'+day+'日')
 
if int(ID_sex)%2==0:
  print('性别:女')
else:
  print('性别:男')
 
   
#此部分应为错误判断,如果错误就不应有上面的输出,如何实现?#
W=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
ID_num=[18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2]
ID_CHECK=['1','0','X','9','8','7','6','5','4','3','2']
ID_aXw=0
for i in range(len(W)):
  
  ID_aXw=ID_aXw+int(ID[i])*W[i]
  
ID_Check=ID_aXw%11
if ID_check==ID_CHECK[ID_Check]:
  print('正确的身份证号码')
else:
  print('错误的身份证号码')

我们再来看一个更加完善些的示例

import re
#Errors=['验证通过!','身份证号码位数不对!','身份证号码出生日期超出范围或含有非法字符!','身份证号码校验错误!','身份证地区非法!']
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)
  #地区校验
  if(not area[(idcard)[0:2]]):
    print 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 )):
      erg=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)):
      print Errors[0]
    else:
      print 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}((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}((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(M == idcard_list[17]):#检测ID的校验位
        print Errors[0]
      else:
        print Errors[3]
    else:
      print Errors[2]
  else:
    print Errors[1]

可以通过命令行输入。第一个命令行参数是身份证号。输出Valid或Invalid。

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
 
USAGE="""\ 
USAGE: python shenfenzheng.py shenfenzhenghao 
""" 
 
chmap = { 
  '0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9, 
  'x':10,'X':10 
  } 
 
def ch_to_num(ch): 
  return chmap[ch]   
 
def verify_string(s): 
  char_list = list(s) 
  num_list = [ch_to_num(ch) for ch in char_list] 
  return verify_list(num_list) 
 
def verify_list(l): 
  sum = 0 
  for ii,n in enumerate(l): 
    i = 18-ii 
    weight = 2**(i-1) % 11 
    sum = (sum + n*weight) % 11 
     
#    print "i=%d,weight=%d,n=%d,sum=%d"%(i,weight,n,sum) 
   
#  print sum 
  return sum==1 
   
if __name__=='__main__': 
  import sys 
  if len(sys.argv)!=2: 
    print USAGE 
    sys.exit(1) 
  result = verify_string(sys.argv[1]) 
  if result: 
    print "Valid" 
  else: 
    print "Invalid"

命令行使用举例:
引用

$ python shenfenzheng.py 320105198209275127
Python 相关文章推荐
简明 Python 基础学习教程
Feb 08 Python
python 解析XML python模块xml.dom解析xml实例代码
Feb 07 Python
浅谈Python处理PDF的方法
Nov 10 Python
Python设计模式之门面模式简单示例
Jan 09 Python
python3检查字典传入函数键是否齐全的实例
Jun 05 Python
PyTorch-GPU加速实例
Jun 23 Python
python实现网页录音效果
Oct 26 Python
python批量合成bilibili的m4s缓存文件为MP4格式 ver2.5
Dec 01 Python
python中@contextmanager实例用法
Feb 07 Python
详解Python牛顿插值法
May 11 Python
利用Python第三方库实现预测NBA比赛结果
Jun 21 Python
浅析Python OpenCV三种滤镜效果
Apr 11 Python
实例Python处理XML文件的方法
Aug 31 #Python
通过实例浅析Python对比C语言的编程思想差异
Aug 30 #Python
使用Python脚本将文字转换为图片的实例分享
Aug 29 #Python
Python中常见的数据类型小结
Aug 29 #Python
深入解析Python中的lambda表达式的用法
Aug 28 #Python
两个使用Python脚本操作文件的小示例分享
Aug 27 #Python
简介二分查找算法与相关的Python实现示例
Aug 26 #Python
You might like
php实现用已经过去多长时间的方式显示时间
2015/06/05 PHP
PHP中生成UUID自定义函数分享
2015/06/10 PHP
代码精简的可以实现元素圆角的js函数
2007/07/21 Javascript
jsTree树控件(基于jQuery, 超强悍)[推荐]
2009/09/01 Javascript
JavaScript判断DOM何时加载完毕的技巧
2012/11/11 Javascript
JS循环遍历JSON数据的方法
2014/07/08 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
探讨JavaScript中的Rest参数和参数默认值
2015/07/29 Javascript
jQuery Mobile框架中的表单组件基础使用教程
2016/05/17 Javascript
深入理解JQuery循环绑定事件
2016/06/02 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
深入浅析jQuery对象$.html
2016/08/22 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
通过实例学习React中事件节流防抖
2019/06/17 Javascript
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
JS实现时间校验的代码
2020/05/25 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
Node.js中的异步生成器与异步迭代详解
2021/01/31 Javascript
python解析json实例方法
2013/11/19 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
pyqt5 从本地选择图片 并显示在label上的实例
2019/06/13 Python
Python实现Mysql数据统计及numpy统计函数
2019/07/15 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
2019/12/19 Python
Pytorch 神经网络—自定义数据集上实现教程
2020/01/07 Python
荷兰在线啤酒店:Beerwulf
2019/08/26 全球购物
西铁城美国官方网站:Citizen Watch美国
2019/11/08 全球购物
eharmony澳大利亚:网上约会服务
2020/02/29 全球购物
泰国第一在线超市:Tops
2021/02/13 全球购物
司机工作自我鉴定
2014/09/19 职场文书
2015年世界卫生日活动总结
2015/02/09 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
2015年度校学生会工作总结报告
2015/05/23 职场文书
七年级作文之环保作文
2019/10/17 职场文书
Python基于百度AI实现抓取表情包
2021/06/27 Python