首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
拉钩
V2EX  ›  Python

Python的良民证算法

  •  
  •   phuslu · 2012-09-14 14:35:52 +08:00 · 5936 次点击
    这是一个创建于 2283 天前的主题,其中的信息可能已经有所发展或是发生改变。
    based on @est version
    http://www.newsmth.net/bbstcon.php?board=Python&gid=95585

    >>> get_id = lambda s: s[:17]+'10X98765432'[sum(int(a)*(int(b)+1) for a,b in zip(s,'68947310526894731'))%11]
    >>> get_id('34052419800101001')
    '34052419800101001X'
    13 回复  |  直到 1970-01-01 08:00:00 +08:00
        1
    est   2012-09-14 14:51:46 +08:00
    @phuslu 你是goagent作者?厉害啊。。。
        2
    phuslu   2012-09-14 15:00:19 +08:00
    @est 过奖啦,对你神交已久了~~
        3
    phuslu   2012-09-14 15:15:45 +08:00   ♥ 1
    http://www.newsmth.net/bbscon.php?bid=284&id=95592

    get_id = lambda s: s + '1X864209753'[int(s, 13) % 11]
        4
    est   2012-09-14 15:26:14 +08:00
    @phuslu 这个是错的。原版算法如下:

    http://www.keakon.net/2009/03/07/%E7%94%A8Python%E8%AE%A1%E7%AE%97%E8%BA%AB%E4%BB%BD%E8%AF%81%E6%A0%A1%E9%AA%8C%E7%A0%81



    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。
        5
    shector   2012-09-15 22:19:50 +08:00
    @est 那个没错吧,系数其实是 2^i % 11 (i 从右侧算起),当作 13 进制的话乘的 (11 + 2)^i % 11 正好是 2^i % 11.
        6
    aristotle9   2012-09-16 00:20:40 +08:00
    @shector
    是这样的,不过13进制的最右位指数是0而不是1,导致结果的余数是原来余数乘13前的余数,最终的查找表作相应的修正:
    "1X864209753",生成代码(Haskell)为
    ["10x98765432" !! (x * 2 `mod` 11) | x <- [0..10]]
        7
    ivanlw   2012-09-16 01:16:58 +08:00
    @est 怎么看出来是g的作者的……
        8
    alex_ilex   2012-09-16 01:32:10 +08:00
    @ivanlw 看个人信息的Github页面...I guess
        9
    fuxkcsdn   2012-09-16 11:30:11 +08:00
    get_id('12345678910111213')
    虽然简短,但完全没验证...
    JS蛋疼版
    function getId(s){for(var i=0,n=0;i<17;)n+=parseInt(s.charAt(i),10)*(parseInt("68947310526894731".charAt(i++),10)+1);return s.slice(0,17)+"10X98765432".charAt(n%11);}
        10
    Jet   2012-09-16 19:43:19 +08:00
    我靠,从上述数字中惊讶发现了自己的银行密码...
        11
    est   2012-09-20 13:34:12 +08:00
    @phuslu

    又看到一位巨牛更加碉堡的写法了。。

    get_id = lambda s:s+str((1-2*int(s, 13)) % 11).replace('10', 'X')

    给跪了。。。。
        12
    bitsmix   2012-09-20 13:49:37 +08:00
    我写的 coffee 版的 ..

    http://gist.github.com/2203189
        13
    ljbha007   2012-09-20 14:36:34 +08:00
    良民证是什么?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1989 人在线   最高记录 4019   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 21ms · UTC 03:25 · PVG 11:25 · LAX 19:25 · JFK 22:25
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1