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条件和循环的使用方法
Nov 01 Python
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
Jun 09 Python
Python3 socket同步通信简单示例
Jun 07 Python
python编写微信远程控制电脑的程序
Jan 05 Python
Selenium元素的常用操作方法分析
Aug 10 Python
实例分析python3实现并发访问水平切分表
Sep 29 Python
Python队列、进程间通信、线程案例
Oct 25 Python
python之array赋值技巧分享
Nov 28 Python
python 控制台单行刷新,多行刷新实例
Feb 19 Python
python实现图像全景拼接
Mar 27 Python
浅析Python迭代器的高级用法
Jul 16 Python
python基础学习之生成器与文件系统知识总结
May 25 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比较多维数组中值的大小排序实现代码
2012/09/08 PHP
PHP Class&Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
javascript 读取图片文件的大小
2009/06/25 Javascript
jQuery源码分析-02正则表达式 RegExp 常用正则表达式
2011/11/14 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
2013/05/03 Javascript
Express.JS使用详解
2014/07/17 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
2015/08/17 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
Vue常用指令V-model用法
2017/03/08 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
bootstrap模态框弹出和隐藏,动态改变中间内容的实例
2018/08/10 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
vue-for循环嵌套操作示例
2019/01/28 Javascript
elementui之el-tebs浏览器卡死的问题和使用报错未注册问题
2019/07/06 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
phpsir 开发 一个检测百度关键字网站排名的python 程序
2009/09/17 Python
python字符串连接的N种方式总结
2014/09/17 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
python爬取酷狗音乐排行榜
2019/02/20 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
Jabra捷波朗美国官网:用于办公、车载和运动的无线蓝牙耳麦
2017/02/01 全球购物
缅甸网上购物:Shop.com.mm
2017/12/05 全球购物
是否有自动比较结构的方法
2015/06/03 面试题
应用数学专业求职信
2014/03/14 职场文书
学生期末评语大全
2014/04/30 职场文书
美食节目策划方案
2014/05/31 职场文书
2015年世界环境日演讲稿
2015/03/18 职场文书
终止解除劳动合同证明书
2015/06/17 职场文书
2019各种承诺书范文
2019/06/24 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书
Python socket如何解析HTTP请求内容
2022/02/12 Python
MySQL安装失败的原因及解决步骤
2022/06/14 MySQL
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript