Python实现身份证号码解析
中国的居民身份证有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('请输入十八位身份证号码:')
iflen(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+'日')
ifint(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
foriinrange(len(W)):
ID_aXw=ID_aXw+int(ID[i])*W[i]
ID_Check=ID_aXw%11
ifID_check==ID_CHECK[ID_Check]:
print('正确的身份证号码')
else:
print('错误的身份证号码')
我们再来看一个更加完善些的示例
importre
#Errors=['验证通过!','身份证号码位数不对!','身份证号码出生日期超出范围或含有非法字符!','身份证号码校验错误!','身份证地区非法!']
defcheckIdcard(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(notarea[(idcard)[0:2]]):
printErrors[4]
#15位身份号码检测
if(len(idcard)==15):
if((int(idcard[6:8])+1900)%4==0or((int(idcard[6:8])+1900)%100==0and(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)):
printErrors[0]
else:
printErrors[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==0or(int(idcard[6:10])%100==0andint(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的校验位
printErrors[0]
else:
printErrors[3]
else:
printErrors[2]
else:
printErrors[1]
可以通过命令行输入。第一个命令行参数是身份证号。输出Valid或Invalid。
#!/usr/bin/envpython
#-*-coding:utf-8-*-
USAGE="""\
USAGE:pythonshenfenzheng.pyshenfenzhenghao
"""
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
}
defch_to_num(ch):
returnchmap[ch]
defverify_string(s):
char_list=list(s)
num_list=[ch_to_num(ch)forchinchar_list]
returnverify_list(num_list)
defverify_list(l):
sum=0
forii,ninenumerate(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)
#printsum
returnsum==1
if__name__=='__main__':
importsys
iflen(sys.argv)!=2:
printUSAGE
sys.exit(1)
result=verify_string(sys.argv[1])
ifresult:
print"Valid"
else:
print"Invalid"
命令行使用举例:
引用
$pythonshenfenzheng.py320105198209275127