中国的居民身份证有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、将身份证校验码的校验作为前置判断,如果错误就不再解析其他内容,汗,我还不会;
请输入十八位身份证号码: ‘)
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 = “10×98765432”
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