Python實(shí)現(xiàn)身份證號(hào)碼解析
中國(guó)的居民身份證有18位。其中前17位是信息碼,最后1位是校驗(yàn)碼。每位信息碼可以是0-9的數(shù)字,而校驗(yàn)碼可以是0-9或X,其中X表示10。
身份證校驗(yàn)碼算法:
設(shè)18位身份證號(hào)序列從左到右為:
引用
a[0], a[1], a[2], a[3], ..., a[16], a[17]
其中a[i]表示第i位數(shù)字,i=0,1,2,...,17,如果最后一位(校驗(yàn)位)是X,則a[17]=10
每一位被賦予一個(gè)“權(quán)值”,其中,第i位的權(quán)值w[i]的計(jì)算方法是:
引用
w[i] = 2**(17-i) % 11
其中,i=0,1,2,3,...,17,運(yùn)算符按Python慣例:x**y表示x的y次方,x%y表示x除以y的余數(shù)。
如果一個(gè)身份證號(hào)是正確的,那么:
引用
(a[0]*w[0] + a[1]*w[1] + a[2]*w[2] + ... + a[16]*w[16] + a[17]*w[17]) % 11 == 1
實(shí)際上,校驗(yàn)位a[17]的計(jì)算方法,就是巧妙地選擇一個(gè)值使得上式成立。
根據(jù)上述算法,下面是一個(gè)驗(yàn)證身份證號(hào)正確性的程序。
初學(xué)者————代碼沒(méi)有什么依照編寫規(guī)范,流水賬的模式。還有兩個(gè)功能沒(méi)有實(shí)現(xiàn):
1、依照身份證號(hào)碼的區(qū)域代碼解析所在區(qū)域;
2、將身份證校驗(yàn)碼的校驗(yàn)作為前置判斷,如果錯(cuò)誤就不再解析其他內(nèi)容,汗,我還不會(huì);
ID=input('請(qǐng)輸入十八位身份證號(hào)碼: ') if len(ID)==18: print("你的身份證號(hào)碼是 "+ID) else: print("錯(cuò)誤的身份證號(hào)碼") ID_add=ID[0:6] ID_birth=ID[6:14] ID_sex=ID[14:17] ID_check=ID[17] #ID_add是身份證中的區(qū)域代碼,如果有一個(gè)行政區(qū)劃代碼字典,就可以用獲取大致地址# 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('性別:男') #此部分應(yīng)為錯(cuò)誤判斷,如果錯(cuò)誤就不應(yīng)有上面的輸出,如何實(shí)現(xiàn)?# 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('正確的身份證號(hào)碼') else: print('錯(cuò)誤的身份證號(hào)碼')
我們?cè)賮?lái)看一個(gè)更加完善些的示例
import re #Errors=['驗(yàn)證通過(guò)!','身份證號(hào)碼位數(shù)不對(duì)!','身份證號(hào)碼出生日期超出范圍或含有非法字符!','身份證號(hào)碼校驗(yàn)錯(cuò)誤!','身份證地區(qū)非法!'] def checkIdcard(idcard): Errors=['驗(yàn)證通過(guò)!','身份證號(hào)碼位數(shù)不對(duì)!','身份證號(hào)碼出生日期超出范圍或含有非法字符!','身份證號(hào)碼校驗(yàn)錯(cuò)誤!','身份證地區(qū)非法!'] area={"11":"北京","12":"天津","13":"河北","14":"山西","15":"內(nèi)蒙古","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":"臺(tái)灣","81":"香港","82":"澳門","91":"國(guó)外"} idcard=str(idcard) idcard=idcard.strip() idcard_list=list(idcard) #地區(qū)校驗(yàn) if(not area[(idcard)[0:2]]): print Errors[4] #15位身份號(hào)碼檢測(cè) 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}$')#//測(cè)試出生日期的合法性 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}$')#//測(cè)試出生日期的合法性 if(re.match(ereg,idcard)): print Errors[0] else: print Errors[2] #18位身份號(hào)碼檢測(cè) 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]$')#//閏年出生日期的合法性正則表達(dá)式 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]$')#//平年出生日期的合法性正則表達(dá)式 #//測(cè)試出生日期的合法性 if(re.match(ereg,idcard)): #//計(jì)算校驗(yàn)位 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]#判斷校驗(yàn)位 if(M == idcard_list[17]):#檢測(cè)ID的校驗(yàn)位 print Errors[0] else: print Errors[3] else: print Errors[2] else: print Errors[1]
可以通過(guò)命令行輸入。第一個(gè)命令行參數(shù)是身份證號(hào)。輸出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
相關(guān)文章
Python描述數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之哈夫曼樹篇
這篇文章主要給大家介紹了關(guān)于Python描述數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之哈夫曼樹篇的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09解決pandas read_csv 讀取中文列標(biāo)題文件報(bào)錯(cuò)的問(wèn)題
今天小編就為大家分享一篇解決pandas read_csv 讀取中文列標(biāo)題文件報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python中的__new__與__init__魔術(shù)方法理解筆記
這篇文章主要介紹了Python中的__new__與__init__魔術(shù)方法理解筆記,需要的朋友可以參考下2014-11-11Python鏈?zhǔn)秸{(diào)用數(shù)據(jù)處理實(shí)際應(yīng)用實(shí)例探究
本文將深入介紹Python鏈?zhǔn)秸{(diào)用的概念、原理以及實(shí)際應(yīng)用,通過(guò)豐富的示例代碼,幫助讀者更全面地理解和應(yīng)用這一編程技巧2024-01-01python tqdm實(shí)現(xiàn)進(jìn)度條的示例代碼
這篇文章主要介紹了python tqdm實(shí)現(xiàn)進(jìn)度條的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11python條件變量之生產(chǎn)者與消費(fèi)者操作實(shí)例分析
這篇文章主要介紹了python條件變量之生產(chǎn)者與消費(fèi)者操作,結(jié)合具體實(shí)例形式分析了Python條件變量的概念、原理、及線程操作的相關(guān)技巧,需要的朋友可以參考下2017-03-03深度學(xué)習(xí)Tensorflow2.8?使用?BERT?進(jìn)行文本分類
這篇文章主要為大家介紹了深度學(xué)習(xí)Tensorflow2.8?使用?BERT?進(jìn)行文本分類示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Jupyter導(dǎo)入自定義模塊及導(dǎo)入后TypeError錯(cuò)誤問(wèn)題及解決
這篇文章主要介紹了Jupyter導(dǎo)入自定義模塊及導(dǎo)入后TypeError錯(cuò)誤問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01在python中利用最小二乘擬合二次拋物線函數(shù)的方法
今天小編就為大家分享一篇在python中利用最小二乘擬合二次拋物線函數(shù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12