简单分析
结构
我国的居民身份证号码是特征组合码,由十七位数字本体码和一位校验码组成。 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
六位数字地址码
第一、二位表示省级行政区。 第一位数字是以前的大区制代码。第二位是大区所在省市编码。
- 华北三省二市
- 东北三省
- 华东六省一市
- 华南六省
- 西南四省一市
- 西北五省
- 台湾省
- 香港澳门
具体省(直辖市,自治区,特别行政区)编码如下
- 11~15 京津冀晋蒙
- 21~23 辽吉黑
- 31~37 沪苏浙皖闽赣鲁
- 41~46 豫鄂湘粤桂琼
- 50~54 渝川贵云藏
- 61~65 陕甘青宁新
- 71 台湾
- 81~82 港澳
记不住省份简称的可以跳过去看看 https://blog.csdn.net/qq_55342245/article/details/113815397
第三、四位表示地级行政区。01一般表示本省省会
就像车牌,A表示本省省会,B一般是本省的二线城市 辽A是沈阳 辽B是大连,黑A是哈尔滨 黑B是齐齐哈尔,川A是成都 川B是绵阳,云A是昆明 云南没有B的牌照
第五、六位表示县级行政区。01一般表示本市市辖区
210101辽宁省沈阳市市辖区 210201辽宁省大连市市辖区 230101黑龙江省哈尔滨市市辖区 230201黑龙江省齐齐哈尔市市辖区 510101四川省成都市市辖区 510701四川省绵阳市市辖区
八位数字出生日期码
(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。
三位数字顺序码
(身份证号码第十五位到十七位)表示在同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。(我国古代,奇数为阳,偶数为阴)
一位数字校验码
根据前面十七位数字码,按按一定规则计算出来。 公式:最后一位
=
(
12
?
∑
i
=
2
18
a
i
w
i
m
o
d
11
)
m
o
d
11
= ( 12- \sum_{i=2}^{18}a_{i}w_{i} mod 11) mod11
=(12?∑i=218?ai?wi?mod11)mod11
mod 是取余数的意思。 例(36 mod 5)=1, (46 mod 8)=6 ai 是从右往左数第i位,加权因子wi = 2(i-1) mod 11 身份证是18位,所以a2是倒数第二位,正数第17位
因为最后一位是除以11取余数得到,就有0~10这十一种情况,那么就得用X(X是罗马数字的10)来代替10,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准。
十八位身份证还可以用这个公式验证:
∑
i
=
1
18
a
i
w
i
≡
1
(
m
o
d
11
)
\sum_{i=1}^{18}a_{i}w_{i} \equiv 1 ( mod 11)
∑i=118?ai?wi?≡1(mod11)
“
≡
\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
这个公式的另一种写法是:
(
∑
i
=
1
18
a
i
w
i
)
m
o
d
11
=
1
( \sum_{i=1}^{18}a_{i}w_{i}) mod 11 = 1
(∑i=118?ai?wi?)mod11=1
安利几个千年难遇的身份证号(虽然合法,但不一定真实存在。如有冒犯请评论删除) 这些身份证是有意义的。但形成这样的身份证号,必须是公安机关分配给你的顺序码由0和2组成,而且0和2的还得有一个正确的搭配顺序 有兴趣的还可以自己多找几个 220202200002022002 吉林省吉林市昌邑区2000年2月2日出生的女孩 220202200002200200 吉林省吉林市昌邑区2000年2月20日出生的女孩 220202202002020022 吉林省吉林市昌邑区2020年2月2日出生的女孩 220202202002022220 吉林省吉林市昌邑区2020年2月2日出生的女孩 220202202002202002 吉林省吉林市昌邑区2020年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']
if id[17]==rem[j]:
return True
else:
return False
li = []
area = '220202'
year = ['2000','2002','2020','2022']
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 + m
if 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)
专业的 公式:
a
1
=
(
12
?
∑
i
=
2
18
m
o
d
11
)
m
o
d
11
a_{1}= ( 12- \sum_{i=2}^{18} mod 11) mod11
a1?=(12?∑i=218?mod11)mod11
def Judge(id):
sum = 0
for i in range(17):
wi = 1
wi <<= 17-i
wi %= 11
sum += int(id[i]) * wi
print(f"校验码是:{(12-sum%11)%11}")
id = '9153455276589485465110'
Judge(id)
验证并提取信息
import datetime
now = datetime.datetime.now()
now = str(now)
def Judge(id):
sum = 0
for i in range(17):
wi = 1
wi <<= 17-i
wi %= 11
sum += int(id[i]) * wi
mo = (12-sum%11)%11
if 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 True
else:
return False
def Month(id):
m = int(id[10:12])
if m>=1 and m<=12:
return True
else:
return False
def 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 True
if m in [4,6,9,11]:
if d>=1 and d<=30:
return True
if m==2:
if y%4==0 and y%100!=0 or y%400==0:
if d>=1 and d<=29:
return True
else:
if d>=1 and d<=28:
return True
else:
return False
if __name__ == '__main__':
id = '220202200002022002'
id = '220202202002022220'
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('输入有误,该身份证不合法。。。')
|