生活随笔
收集整理的這篇文章主要介紹了
用Python计算身份证校验码
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)自:http://my.oschina.net/moooofly/blog/147958
原來(lái)的天朝良民證是15位,構(gòu)成如下:?
1~6位:地址碼。采用的是行政區(qū)劃代碼,可以去?統(tǒng)計(jì)局的網(wǎng)站?查。?
7~12位:生日期碼。構(gòu)成為yymmdd。?
13~15位:順序碼。每個(gè)地區(qū)出生人口按順序遞增,最后一位奇數(shù)分給男的,偶數(shù)分給女的。?
18位則有2點(diǎn)改動(dòng):?
1.生日期碼變?yōu)?位,構(gòu)成為yyyymmdd。?
2.增加校驗(yàn)碼,即第18位。按照ISO 7064:1983.MOD 11-2校驗(yàn)碼計(jì)算。?
計(jì)算方法很無(wú)聊:?
將身份證號(hào)碼的前17位數(shù)分別乘以不同的系數(shù)。從第一位到第十七位的系數(shù)分別為:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2?
將這17位數(shù)字和系數(shù)相乘的結(jié)果相加。
用加出來(lái)和除以11,得到余數(shù)。
余數(shù)的結(jié)果只可能為0 1 2 3 4 5 6 7 8 9 10這11種,分別對(duì)應(yīng)的最后一位身份證的號(hào)碼為1 0 X 9 8 7 6 5 4 3 2。
弄懂這個(gè)后,很快就能寫(xiě)出Python的計(jì)算程序了:
??
| 1 | s?=?"34052419800101001"?#這個(gè)是要查的身份證號(hào)碼的前17位 |
| 4 | sum?=?int(s[0])?*?7?+?int(s[1])?*?9?+?int(s[2])?*?10?+?int(s[3])?*?5?+?int(s[4])?*?8?+?int(s[5])?*?4?+?int(s[6])?*?2?+?int(s[7])?*?1?+?int(s[8])?*?6?+?int(s[9])?*?3?+?int(s[10])?*?7?+?int(s[11])?*?9?+?int(s[12])?*?10?+?int(s[13])?*?5?+?int(s[14])?*?8?+?int(s[15])?*?4?+?int(s[16])?*?2 |
| 7 | print?'10X98765432'[sum?%?11] |
有沒(méi)有覺(jué)得計(jì)算總和非常無(wú)語(yǔ),下面來(lái)簡(jiǎn)化代碼:
??
| 01 | s?=?"34052419800101001" |
| 04 | temp?=?zip(s[0:17], [7,?9,?10,?5,?8,?4,?2,?1,?6,?3,?7,?9,?10,?5,?8,?4,?2]) |
| 08 | temp2?=?map(lambda?x:int(x[0])*x[1], temp) |
| 14 | #temp3 = reduce(lambda x, y : x + y, temp2) |
| 18 | print?'10X98765432'[temp3?%?11] |
| 21 | print?'10X98765432'[sum(map(lambda?x:?int(x[0])?*?x[1],?zip(s[0:17], [7,?9,?10,?5,?8,?4,?2,?1,?6,?3,?7,?9,?10,?5,?8,?4,?2]) ))?%?11] |
| 22 | #print '10X98765432'[reduce(lambda x, y: x + y, map(lambda x: int(x[0]) * x[1], zip(s[0:17], [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]) )) % 11] |
可能不熟悉Python的還看不懂怎么zip、map和reduce的作用,我再解釋下吧。(sum太簡(jiǎn)單了,就不說(shuō)了,相當(dāng)于reduce的簡(jiǎn)化版。)
?
zip是迭代各個(gè)參數(shù),并返回一個(gè)元組的列表。第i個(gè)元組由參數(shù)的第i個(gè)元素組成。當(dāng)一個(gè)參數(shù)迭代完成后,就結(jié)束zip,其余參數(shù)未迭代的部分忽略。
?
舉例來(lái)說(shuō):
??
| 04 | [(1,?4), (2,?5), (3,?6)] |
| 05 | >>>?zip([1,?2],?*[(3,?4), (5,?6)])?#星號(hào)(*)是把列表的元素轉(zhuǎn)換為參數(shù) [(1, 3, 5), (2, 4, 6)] |
| 06 | >>>?zip(*zip(a, b))?#相當(dāng)于unzip [(1, 2, 3), (4, 5, 6)] |
| 07 | >>> (x, y)?=?zip(*zip(a, b)) |
| 14 | [(1,?7), (2,?8), (3,?9)] |
| 16 | [(1,?4,?7), (2,?5,?8), (3,?6,?9)] |
| 17 | >>> d?=?'abcd'?>>>?zip(c, d) |
| 18 | [(7,?'a'), (8,?'b'), (9,?'c'), (10,?'d')] |
map則是將一個(gè)函數(shù)迭代處理各個(gè)參數(shù),返回結(jié)果列表。與zip不同的是,如果有個(gè)參數(shù)比較短,迭代完它后將用None來(lái)代替不足的元素,如果None不支持該操作,可能會(huì)拋出異常。
?
演示:
??
| 01 | >>>?map(lambda?x:?2?*?x, [1,?2,?3]) |
| 03 | >>>?map(lambda?x: x[0]?+?x[1], [(1,?4), (2,?5), (3,?6)]) |
| 05 | >>>?map(lambda?x, y: x?+?y, [1,?2,?3], [4,?5,?6]) |
| 07 | >>>?map(lambda?x, y: x?+?y, [1,?2,?3], [4,?5,?6,?7]) |
| 08 | Traceback (most recent call last): |
| 09 | ??File?"<stdin>", line?1,?in?<module> |
| 10 | ??File?"<stdin>", line?1,?in?<lambda> |
| 11 | TypeError: unsupported operand?type(s)?for?+:?'NoneType'?and?'int'?#最后的None + 7會(huì)出錯(cuò) |
reduce是用一個(gè)函數(shù)從左至右依次迭代處理各個(gè)元素,并返回最后的總結(jié)果。此外,如果有第3個(gè)參數(shù)的話(huà),會(huì)將第3個(gè)參數(shù)當(dāng)成初始值。
??
| 01 | >>>?reduce(lambda?x, y: x?+?y, [1,?2,?3,?4,?5])?#計(jì)算((((1+2)+3)+4)+5) |
| 03 | >>>?reduce(lambda?x, y: x?+?y,?range(101))?#從1加到100 |
| 05 | >>>?reduce(lambda?x, y: x?*?y,?range(1,?11))?#計(jì)算10的階乘 |
| 07 | >>>?print?reduce(lambda?x, y:?str(x)?+?str(y),?range(11),?'輸出1~10: ') |
| 09 | >>>?print?reduce(lambda?x, y: (x?+?'%d')?%?y,?range(11),?'輸出0~10: ') |
| 11 | >>>?print?(lambda?n, m:?reduce(lambda?x, y: x?+?n?**?y,?xrange(m?+?1)))(3,?4)?#計(jì)算n+n^2+n^3....n^m,n和m我給了4 |
| 13 | >>> (lambda?n:?reduce(lambda?x, y: x?*?y,?xrange(1, n?+?1)))(10)?# 計(jì)算10的階乘(雖然我沒(méi)優(yōu)化算法,但計(jì)算10000的階乘也不用1秒) |
Python果然是非常方便的東西啊~
?
========== 我是分割線(xiàn) =============
?
PS:原文的 URL 中帶中文,在原文鏈接中無(wú)法給全,特此注明。引用自這里。
?
總結(jié)
以上是生活随笔為你收集整理的用Python计算身份证校验码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。