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