大陆地区18位身份证校验码算法
2021-09-03 11:24:09 Author: mp.weixin.qq.com(查看原文) 阅读量:47 收藏

创建: 2021-09-02 11:42
更新: 2021-09-03 10:07
http://scz.617.cn:8/python/202109021142.txt

今天看gantrol贴了这个函数

def checksum ( s ) :
    return str( ( 1 - 2 * int( s, 13 ) ) % 11 ).replace( '10''X' )

虽然我一直知道尾号是校验码,但我从未去关注过这个算法。刚才试了一下,对得上。居然是用13进制,这么邪门,不知最初选用这个进制的理由是啥。

晚上想了一下13进制这事,补充点讨论。

上面这个算法实际相当于:

def checksum ( s ) :
    return str( ( int( '-' + s + '0'13 ) + 1 ) % 11 ).replace( '10''X' )

假设18位身份证号是"430101196001011318",这是我杜撰的一个身份证号,勿对号入座。那么,上述算法实际是将字符串"-430101196001011310"(尾数用0替换)视为13进制整数,加1,再模11得到校验码。为了用单个字符,余数是10时用X代替。整个算法就这么简单直白。

>>> checksum('43010119600101131')
'8'

初等数论中定义有"模n的r次同余方程"

设n是正整数,a_i是整数,a_r不是n的倍数(包括0),f(x)是r次多项式:

f(x)=a_r*x^r+a_r_1*x^(r-1)+...+a_2*x^2+a_1*x+a_0

则:

f(x)≡0(mod n)

称作模n的r次同余方程。

由于a_0可以是[0,n)区间的任意整数,所以"模n的r次同余方程"可以写成:

f(x)≡m(mod n)

同余m不一定要求是0。

回头来看大陆地区18位身份证校验码算法,求解"模11的17次同余方程"

f(x)≡1(mod 11)

该高次同余方程的最小正整数解是13。可能是先定了冪17、模11、同余1,然后求解高次同余方程得一解13,13是这么来的。

换句话说,校验18位身份证号时,进行如下运算,结果应该恒为1。

>>> int( '430101196001011318'13 ) % 11
1

当然,由于尾号有可能是X,无法如此简写,但数学原理就是如此简单。

假设将来身份证号进一步升位,冪变、模变、同余变,都有可能,再次求解高次同余方程,仍可套用前述算法框架。

我没有看过原始算法文档,此处仅仅是出于数学爱好瞎讨论一番,不要当真。


文章来源: http://mp.weixin.qq.com/s?__biz=MzUzMjQyMDE3Ng==&mid=2247484758&idx=1&sn=10474595a91838d559b73b749b08567c&chksm=fab2c669cdc54f7f69eebfc0d06bc604e81380b76c955d13fb783b5c081d3b7927a58548157d#rd
如有侵权请联系:admin#unsafe.sh