马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
这是一个新手的练习,请大家指正。
归属地数据文件见附件,下载后去掉.txt后缀。
输入15位身份证转换为18位。输入18位判断校验位是否正确。
根据身份证信息得到:归属地、生日、性别等。
#/usr/bin/env python
# -*- coding:utf-8 -*-
'''
校验位计算依据:
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)计算模
Y = mod(S, 11)
(3)通过模得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
'''
import pickle
import datetime
def borderline(str1,ch='*'):
#函数目的是为一行或多行字符串加上一个边框,更美观的输出,*为缺省边框字符
strLen=0
for each in str1.splitlines():#找出字符串最长一行的字符数
if strLen<len(each.encode('gb2312')):strLen=len(each.encode('gb2312'))
#加上encode('gb2312')是使每个汉字记为2个字符长度
str2=ch*(strLen+6)+'\n'
str2=str2+ch+' '*(strLen+4)+ch+'\n'
for each in str1.splitlines():
str2=str2+ch+' '+each+' '*(strLen-len(each.encode('gb2312'))+2)+ch+'\n'
str2=str2+ch+' '*(strLen+4)+ch+'\n'
str2=str2+ch*(strLen+6)
return str2
def checkDate(str1):
#检查日期数据是否合法
try:
global birthday
birthday=datetime.date(int(str1[6:10]),int(str1[10:12]),int(str1[12:14]))
check=True
except:
check=False
return check
def checkByte(str1):
#计算校验位
w=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
s=0
for i in range(17):
s=s+int(str1[i])*w[i]
check=(1-s)%11#可以s%11再查表得到校验位,根据规律直接计算得出
if check==10:check='X'
check=str(check)
return check
def sex(str1):
#查看性别
if int(str1[-2])%2==0:
return '女'
else:
return '男'
titleStr='''身份证查验系统
可将15位身份证转为18位
可检查校验位是否正确
可查询身份证归属地等信息'''
f=open('iddata.pkl','rb')#打开归属地数据库
#原始归属地数据为excel格式,修改为字典,并按小甲鱼课程所讲pickle到数据文件
idData=pickle.load(f)#读取字典
f.close()
print(borderline(titleStr))
week=('星期一','星期二','星期三','星期四','星期五','星期六','星期日')
while True:
code=input('请输入15位或18位身份证号码,输入“q”退出:')
if code.upper()=='Q':
break
if len(code)!=15 and len(code)!=18:
print('输入位数有误,请重新输入。')
continue
if len(code)==15:
code=code[:6]+'19'+code[6:]+'M'
#15位身份证按19xx年考虑,先转为18位,校验位暂未‘M’,这样方便后面的判断和计算
if not (code[:17].isdigit() and (code[-1].isdigit() or code[-1]=='M' or code[-1].upper()=='X')):
print('输入15位身份证要求全为数字,18位身份证前17位为数字,第18位为数字或字母“X”,请重新输入。')
continue
if idData.get(code[:6])==None:
print('输入的前6位是归属地代码,你输入的归属地查不到,请重新输入。',)
continue
if checkDate(code)==False:
print('15位身份证的7~12位为日期,18位身份证7~14位为日期,输入的日期有误,请重新输入。',)
continue
last=checkByte(code)#计算校验位
if code[-1]=='M':
code=code[:17]+last
print('15位转18位身份证号是:',code)
elif code[-1]!=last:
code=code[:17]+last
print('18位身份证校验错误,正确的号码可能是:',code)
else:
print('18位身份证校验正确。')
print('身份证归属地:',idData[code[:6]])
print('生日:',birthday,week[birthday.weekday()])
print('年龄:',datetime.datetime.now().year-int(code[6:10]))
print('性别:',sex(code))
|