2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 解析身份证号码(Python版)

解析身份证号码(Python版)

时间:2021-04-11 06:33:00

相关推荐

解析身份证号码(Python版)

解析身份证号码(Python版)

简单分析结构六位数字地址码八位数字出生日期码三位数字顺序码一位数字校验码代码实现获取身份证号里的信息获取身份证中的省份计算身份证校验位验证并提取信息

简单分析

结构

我国的居民身份证号码是特征组合码,由十七位数字本体码和一位校验码组成。

排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

六位数字地址码

第一、二位表示省级行政区。

第一位数字是以前的大区制代码。第二位是大区所在省市编码。

华北三省二市东北三省华东六省一市华中华南六省西南四省一市西北五省台湾省香港澳门

具体省(直辖市,自治区,特别行政区)编码如下

11~15 京津冀晋蒙21~23 辽吉黑31~37 沪苏浙皖闽赣鲁41~46 豫鄂湘粤桂琼50~54 渝川贵云藏61~65 陕甘青宁新71 台湾81~82 港澳

记不住省份简称的可以跳过去看看

/qq_55342245/article/details/113815397

第一位表示区域码,第二位表示该区域内的省的编码。

引入区域的概念后,既保持了各省代码的相对连续,又方便了以后对省级行政区划变更的扩展。

比如重庆市以前是隶属于四川省的一个省辖市,升级为直辖市后,新的代码就从西南区域中分配(新分配到的区划代码是50)。假如以后深圳市也有机会升级为直辖市的话,就可以从华南区域分配省级区划代码(比如40)。目前各区域都预留有4~7个代码作为备用。

在一个区域内,编码的顺序是有个优先级的:直辖市,省,自治区。

第三、四位表示市、地区、自治州、盟、直辖市所辖市辖区/县汇总码、省(自治区)直辖县级行政区划汇总码。01一般表示本省省会。其中:

01~20/51~70表示市,01、02还用与表示直辖市所辖市辖区/县汇总码;21~50表示地区、自治州、盟;90表示省(自治区)直辖县级行政区划汇总码。

例如车牌,A表示本省省会,B一般是本省的二线城市

辽A是沈阳 辽B是大连,黑A是哈尔滨 黑B是齐齐哈尔,川A是成都 川B是绵阳,云A是昆明 云南没有B的牌照

第五、六位表示县、自治县、县级市、旗、自治旗、市辖区、林区、特区。01一般表示本市市辖区。其中:

01~20表示市辖区、地区(自治州、盟)辖县级市、市辖特区以及省(自治区)直辖县级行政区划中的县级市,01通常表示市辖区汇总码;21~80表示县、自治县、旗、自治旗、林区、地区辖特区;81~99表示省(自治区)辖县级市。

210101辽宁省沈阳市市辖区 210201辽宁省大连市市辖区

230101黑龙江省哈尔滨市市辖区 230201黑龙江省齐齐哈尔市市辖区

510101四川省成都市市辖区 510701四川省绵阳市市辖区

八位数字出生日期码

(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。

三位数字顺序码

(身份证号码第十五位到十七位)表示在同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。(我国古代,奇数为阳,偶数为阴)

一位数字校验码

根据前面十七位数字码,按一定规则计算出来。

简单版

W里包含17个数,W = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]。

用身份证号的前17位分别对应相乘。从左往右数,第一位乘7,第二位乘9,第三位乘10,,然后将这些结果求和,用和除以11得到一个余数。

REM里包含11个数,REM = [‘1’, ‘0’, ‘X’, ‘9’, ‘8’, ‘7’, ‘6’, ‘5’, ‘4’, ‘3’, ‘2’]。

余数是0,那么最后一位是1;余数是1,那么最后一位是0;余数是2,那么最后一位是X。。。以此类推

专业版

公式:最后一位 =(12−∑i=218aiwimod11)mod11= ( 12- \sum_{i=2}^{18}a_{i}w_{i} \ mod \ 11) \ mod \ 11=(12−∑i=218​ai​wi​mod11)mod11

ai 是从右往左数第i位,加权因子 wi = 2(i-1) mod 11

身份证是18位,所以a2指倒数第二位,正数第17位;a3指倒数第三位,正数第16位

mod 是取余数的意思。 例(36 mod 5)=1(36/5=7余1), (46 mod 8)=6(46/8=5余6)

因为最后一位是除以11取余数得到,就有0~10这十一种情况,那么就得用X(X是罗马数字的10)来代替10,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准。

十八位身份证还可以用这个公式验证:∑i=118aiwi≡1(mod11)\sum_{i=1}^{18}a_{i}w_{i} \equiv 1 ( mod 11)∑i=118​ai​wi​≡1(mod11)

这个公式的另一种写法是:(∑i=118aiwi)mod11=1( \sum_{i=1}^{18}a_{i}w_{i}) mod 11 = 1(∑i=118​ai​wi​)mod11=1

“ ≡\equiv≡ ”是同余符号。 例:

16 ≡\equiv≡ 11 ( mod 5) 16除以5=3余1,11除以5=2余1。余数都是1,二者同余

25 ≡\equiv≡ 3 ( mod 11) 25除以11=2余3,3除以11=0余3。余数都是3,二者同余

安利几个千年难遇的身份证号(虽然合法,但不一定真实存在。如有冒犯请联系删除)

这些身份证是有意义的。但形成这样的身份证号,必须是公安机关分配给你的顺序码由0和2组成,而且0和2的还得有一个正确的搭配顺序

2220000002 吉林省吉林市昌邑区2000年2月2日出生的女孩

22200002200200 吉林省吉林市昌邑区2000年2月20日出生的女孩

220022 吉林省吉林市昌邑区2月2日出生的女孩

220220 吉林省吉林市昌邑区2月2日出生的女孩

220202 吉林省吉林市昌邑区2月20日出生的女孩

def doVerify(id):sum = 0# 身份证的前十七位分别乘以相应的加权因子wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]for i in range(17):sum += int(id[i]) * wi[i]j = sum%11# 根据余数去匹配对应的数字rem = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']# print("校验码是:" + rem[j])if id[17]==rem[j]:return Trueelse:return Falseli = []area = '22'year = ['2000','2002','','']month = '02'day = ['02','20','22']num = ['002','020','022','200','202','220','222']mo = ['0','2']for y in year:for d in day:for n in num:for m in mo:id = area + y + month + d + n + mif doVerify(id):li.append(id)print(li)print(len(li))

代码实现

获取身份证号里的信息

def getInfo(s):area = s[0:6]year = s[6:10]month = s[10:12]day = s[12:14]num = s[14:17]checkCode = s[17]print("地区码:" + area)print(f"出生日期:{year}年{month}月{day}日")print("顺序码:" + num)print("校验码:" + checkCode)print("性别:女") if int(num) % 2 == 0 else print("性别:男")id = '510107199806186520'getInfo(id)

获取身份证中的省份

def getArea(s):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":"澳门特别行政区"}if s[0:2] in area.keys():print(area[s[0:2]])else:print('地区码无效')id = '510107199806186520'getArea(id)

计算身份证校验位

简单的

# (简单)def doVerify(id):sum = 0# 身份证的前十七位分别乘以相应的加权因子wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]# 根据余数去匹配对应的数字rem = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']for i in range(17):sum += int(id[i]) * wi[i]print("校验码是:" + rem[sum%11] )id = '11223223239811110'doVerify(id)

专业的

公式:最后一位 =(12−∑i=218aiwimod11)mod11= ( 12- \sum_{i=2}^{18}a_{i}w_{i} \ mod \ 11) \ mod \ 11=(12−∑i=218​ai​wi​mod11)mod11

def Judge(id):sum = 0for i in range(17):# 加权因子wi = 2^(i-1) mod 11 i从右往左数# 也就是w1 = (2^17) % 11,w2 = (2^16) % 11,w17 = (2^1) % 11wi = 1wi <<= 17-i # 左移,这里相当于乘以2的(17-i)次方wi %= 11 # 计算得到最终的加权因子sum += int(id[i]) * wiprint(f"校验码是:{(12-sum%11)%11}")id = '9153455276589485465110'Judge(id)

验证并提取信息

import datetimenow = datetime.datetime.now()now = str(now)# 判断身份证号检验码def Judge(id):sum = 0for i in range(17):# 加权因子wi = 2^(i-1) mod 11 i从右往左数# 也就是w1 = (2^17) % 11,w2 = (2^16) % 11,w17 = (2^1) % 11wi = 1wi <<= 17-i # 左移,这里相当于乘以2的(17-i)次方wi %= 11 # 计算得到最终的加权因子sum += int(id[i]) * wimo = (12-sum%11)%11if id[17] == str(mo) or ((id[17]=='x' or id[17]=='X') and mo==10):return True# 判断身份证号地区码def Area(id):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":"澳门特别行政区"}if id[0:2] in area.keys():return area[id[0:2]]else:return ''# 判断时间是否合法def Year(id):y = int(id[6:10])if y>=1840 and y<=int(now[0:4]):return Trueelse:return Falsedef Month(id):m = int(id[10:12])if m>=1 and m<=12:return Trueelse:return Falsedef Day(id):y = int(id[6:10])m = int(id[10:12])d = int(id[12:14])if m >= 1 and m <= 12:if m in [1,3,5,7,8,10,12]:if d>=1 and d<=31:return Trueif m in [4,6,9,11]:if d>=1 and d<=30:return Trueif m==2:if y%4==0 and y%100!=0 or y%400==0:if d>=1 and d<=29:return Trueelse:if d>=1 and d<=28:return Trueelse:return Falseif __name__ == '__main__':id = '2220000002'id = '220220'area = Area(id)if len(id)==18 and id[:17].isdigit() and Judge(id) and len(area)!=0 and Year(id) and Month(id) and Day(id):print("身份证号有效")print(f"地区码:{id[0:6]},属于{area}")print(f"出生日期:{id[6:10]}年{id[10:12]}月{id[12:14]}日")print("顺序码:" + id[14:17])print("校验码:" + id[17])print("性别:女") if int(id[16]) % 2 == 0 else print("性别:男")else:print('输入有误,该身份证不合法。。。')

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。