原来的天朝良民证是15位,构成如下:  
1~6位:地址码。采用的是行政区划代码,可以去   统计局的网站   查。  
7~12位:生日期码。构成为yymmdd。  
13~15位:顺序码。每个地区出生人口按顺序递增,最后一位奇数分给男的,偶数分给女的。  

18位则有2点改动:  
1.生日期码变为8位,构成为yyyymmdd。  
2.增加校验码,即第18位。按照ISO 7064:1983.MOD 11-2校验码计算。  

计算方法很无聊:  

  1. 将身份证号码的前17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 
  2. 将这17位数字和系数相乘的结果相加。
  3. 用加出来和除以11,得到余数。
  4. 余数的结果只可能为0 1 2 3 4 5 6 7 8 9 10这11种,分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。

弄懂这个后,很快就能写出Python的计算程序了:   

s           =          "34052419800101001"          #这个是要查的身份证号码的前17位         
                    
          #计算总和         
          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         
                    
          #输出校验码         
          print          '10X98765432'          [          sum          %          11          ]



有没有觉得计算总和非常无语,下面来简化代码:

s           =          "34052419800101001"         
                    
          #分组         
          temp           =          zip          (s[          0          :          17          ], [          7          ,           9          ,           10          ,           5          ,           8          ,           4          ,           2          ,           1          ,           6          ,           3          ,           7          ,           9          ,           10          ,           5          ,           8          ,           4          ,           2          ])         
          print          temp         
                    
          #相乘         
          temp2           =          map          (          lambda          x:          int          (x[          0          ])          *          x[          1          ], temp)         
          print          temp2         
                    
          #相加         
          temp3           =          sum          (temp2)         
          #或者这样写:         
          #temp3 = reduce(lambda x, y : x + y, temp2)         
          print          temp3         
                    
          #最终结果         
          print          '10X98765432'          [temp3           %          11          ]         
                    
          #写成一行代码就是这样         
          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          ]         
          #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太简单了,就不说了,相当于reduce的简化版。)

 


zip是迭代各个参数,并返回一个元组的列表。第i个元组由参数的第i个元素组成。当一个参数迭代完成后,就结束zip,其余参数未迭代的部分忽略。

 

举例来说:

>>> a           =          [          1          ,           2          ,           3          ]         
          >>> b           =          [          4          ,           5          ,           6          ]         
          >>>           zip          (a, b)         
          [(          1          ,           4          ), (          2          ,           5          ), (          3          ,           6          )]         
          >>>           zip          ([          1          ,           2          ],           *          [(          3          ,           4          ), (          5          ,           6          )])           #星号(*)是把列表的元素转换为参数 [(1, 3, 5), (2, 4, 6)]         
          >>>           zip          (          *          zip          (a, b))           #相当于unzip [(1, 2, 3), (4, 5, 6)]         
          >>> (x, y)           =          zip          (          *          zip          (a, b))         
          >>> x         
          (          1          ,           2          ,           3          )         
          >>> y         
          (          4          ,           5          ,           6          )         
          >>> c           =          [          7          ,           8          ,           9          ,           10          ]         
          >>>           zip          (a, c)         
          [(          1          ,           7          ), (          2          ,           8          ), (          3          ,           9          )]         
          >>>           zip          (a, b, c)         
          [(          1          ,           4          ,           7          ), (          2          ,           5          ,           8          ), (          3          ,           6          ,           9          )]         
          >>> d           =          'abcd'          >>>           zip          (c, d)         
          [(          7          ,           'a'          ), (          8          ,           'b'          ), (          9          ,           'c'          ), (          10          ,           'd'          )]



map则是将一个函数迭代处理各个参数,返回结果列表。与zip不同的是,如果有个参数比较短,迭代完它后将用None来代替不足的元素,如果None不支持该操作,可能会抛出异常。

 

演示:

>>>           map          (          lambda          x:           2          *          x, [          1          ,           2          ,           3          ])         
          [          2          ,           4          ,           6          ]         
          >>>           map          (          lambda          x: x[          0          ]           +          x[          1          ], [(          1          ,           4          ), (          2          ,           5          ), (          3          ,           6          )])         
          [          5          ,           7          ,           9          ]         
          >>>           map          (          lambda          x, y: x           +          y, [          1          ,           2          ,           3          ], [          4          ,           5          ,           6          ])         
          [          5          ,           7          ,           9          ]         
          >>>           map          (          lambda          x, y: x           +          y, [          1          ,           2          ,           3          ], [          4          ,           5          ,           6          ,           7          ])         
          Traceback (most recent call last):         
                    File          "<stdin>"          , line           1          ,           in          <module>         
                    File          "<stdin>"          , line           1          ,           in          <          lambda          >         
          TypeError: unsupported operand           type          (s)           for          +          :           'NoneType'          and          'int'          #最后的None + 7会出错



reduce是用一个函数从左至右依次迭代处理各个元素,并返回最后的总结果。此外,如果有第3个参数的话,会将第3个参数当成初始值。

  

>>>           reduce          (          lambda          x, y: x           +          y, [          1          ,           2          ,           3          ,           4          ,           5          ])           #计算((((1+2)+3)+4)+5)         
          15         
          >>>           reduce          (          lambda          x, y: x           +          y,           range          (          101          ))           #从1加到100         
          5050         
          >>>           reduce          (          lambda          x, y: x           *          y,           range          (          1          ,           11          ))           #计算10的阶乘         
          3628800         
          >>>           print          reduce          (          lambda          x, y:           str          (x)           +          str          (y),           range          (          11          ),           '输出1~10: '          )         
          输出          1          ~          10          :           012345678910         
          >>>           print          reduce          (          lambda          x, y: (x           +          '%d'          )           %          y,           range          (          11          ),           '输出0~10: '          )         
          输出          0          ~          10          :           012345678910         
          >>>           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         
          120         
          >>> (          lambda          n:           reduce          (          lambda          x, y: x           *          y,           xrange          (          1          , n           +          1          )))(          10          )           # 计算10的阶乘(虽然我没优化算法,但计算10000的阶乘也不用1秒)         
          3628800



Python果然是非常方便的东西啊~