> 백엔드 개발 > 파이썬 튜토리얼 > Python实现身份证号码解析

Python实现身份证号码解析

不言
풀어 주다: 2018-05-16 16:56:23
원래의
10161명이 탐색했습니다.

中国的居民身份证有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、将身份证校验码的校验作为前置判断,如果错误就不再解析其他内容,汗,我还不会;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

ID=input('请输入十八位身份证号码: ')

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('错误的身份证号码')

로그인 후 복사

我们再来看一个更加完善些的示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

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 = "10X98765432"

      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。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#!/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"

로그인 후 복사

命令行使用举例:
引用

1

$ python shenfenzheng.py 320105198209275127

로그인 후 복사


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿