需求
在用户数据清洗中需要简单地判断身份证的有效性,单并不想通过相关接口进行验证。
身份证验证
- 将前面的身份证号码17位数分别乘以不同的系数。
- 从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
- 将这17位数字和系数相乘的结果相加;
- 用加出来和除以11,查看余数;
- 余数可能为0 1 2 3 4 5 6 7 8 9 10这11个数字,分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2;
- 身份证号分18位和15位,15位身份证号或许还有在使用中的,这里不做额外的考虑
- 身份证号的前6为为户籍所在地可以通过行政区划简单判断
全国行政区划
Python代码
class Verificate():
def __init__(self):
self.idx18=[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
self.end18=[1, 0, 'X', 9, 8 ,7 ,6, 5, 4 ,3, 2]
self.leapm=[1,3,5,7,8,10,12]
self.nleap=[4,5,9,11]
self.xzqh=[]
self.getXZQHfromMaster()
def verificate18(self,IDcard:str):
if len(IDcard)!=18:
return None
card17, card18 = IDcard[:17], IDcard[17:]
if not card17.isdigit():
return None
if not self.isBirthday8(card17[6:14]):
return None
if IDcard[:6] not in self.xzqh:
return None
sum=0
for idx,num in enumerate(card17):
sum+=self.idx18[idx]*int(num)
mod=divmod(sum,11)[1]
endnum=self.end18[mod]
print(endnum)
if endnum=='X':
if card18 not in ['x','X']:
return None
else:
if not card18.isdigit():
return None
else:
if endnum!=int(card18):
return None
else:
return IDcard
def verificate15(self,IDcard:str):
if len(IDcard)!=15:
return None
if not IDcard.isdigit():
return None
if not self.isBirthday6(IDcard[6:12]):
return None
if IDcard[:6] in self.xzqh:
return IDcard
else:
return None
def isLeapyear(self,year:int):
'''
判断是否闰年
:param year:
:return:闰年返回True,否则返回False
'''
if year % 100 == 0:
_module = year % 400
else:
_module = year % 4
if _module:
return False
else:
return True
def isBirthday8(self,date:str):
# 闰月列表
_leapmonth = [1, 3, 5, 7, 8, 10, 12]
_nonleapmonth=[4,6,9,11]
if not date:
return False
try:
_year, _month, _day = int(date[:4]),int(date[4:6]),int(date[6:8])
except:
return False
else:
if _month in _leapmonth :
if _day in Interval(1,31):
return True
else:
return False
elif _month==2:
if self.isLeapyear(_year):
if _day in Interval(1,28):
return True
else:
return False
else:
if _day in Interval(1,27):
return True
else:
return False
elif _month in _nonleapmonth:
if _day in Interval(1, 30):
return True
else:
return False
else:
return False
def isBirthday6(self,date:str):
# 闰月列表
_leapmonth = [1, 3, 5, 7, 8, 10, 12]
_nonleapmonth=[4,6,9,11]
if not date:
return False
try:
_year, _month, _day = int(date[:2]),int(date[2:4]),int(date[4:6])
except:
return False
else:
if _month in _leapmonth :
if _day in Interval(1,31):
return True
else:
return False
elif _month==2:
if self.isLeapyear(_year+1900):
if _day in Interval(1,28):
return True
else:
return False
else:
if _day in Interval(1,27):
return True
else:
return False
elif _month in _nonleapmonth:
if _day in Interval(1, 30):
return True
else:
return False
else:
return False
def getXZQHfromMaster(self):
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
master=Master()
try:
dns=oracle.makedsn(master.host,master.port,master.sid)
con=oracle.connect(master.user,master.psword,dns)
except Exception as err:
print(str(err))
else:
print(con.version)
cur=con.cursor()
datas=cur.execute(master.sqlxzqh)
for item in datas:
self.xzqh.append(item[0])
finally:
if cur:cur.close()
if con:con.close()