2.4.2 身份证校验码
在了解模运算后可以进一步了解生活中模运算的应用,比如人们经常会使用的身份证号就含有模运算。
1999年8月26日,中华人民共和国国务院发布《国务院关于实行公民身份号码制度的决定》,规定中国公民身份号码按照《公民身份号码》(GB 11643-1999)进行编制,由18位数字组成:前6位为行政区划代码(地址码),第7~14位为出生日期码,第位为顺序码,第18位为校验码。整个身份号码组合的方式如表2-1所示。
表2-1 身份号码组合方式
行政区划代码是指公民常住户口所在市(县、镇、区)的识别码。代码编码一共有6位数,共3层,每层2位数。第一层是省级行政区划代码,第二层是地级行政区划代码,第三层是县级行政区划代码。还有第四、第五层行政区划代码,代表乡、村级,但在身份证中不使用。不同地区的行政区划代码可参考《中华人民共和国行政区划代码》(GB/T 2260—2007)。例如440112就代表广东省广州市黄埔区, 110108就代表北京市海淀区。
出生日期码非常好理解,一共8位数,前面4位是出生公历年,然后是月、日。比如1999年9月9日出生的人的出生日期码就是19990909。
顺序码一共3位数,是给相同行政区划代码和出生日期码的人编定的顺序号,奇数分配给男性,偶数分配给女性。如223代表一名男性; 224代表一名女性。
最后一位校验码则是模运算的经典应用。校验码可以帮助人们在录入身份证号过程中检查号码是否有错误,实现快速检测功能。校验码的计算方法是MOD 11-2。顾名思义, MOD就是模运算, 11则代表模11,2是生成元。计算校验码的公式为:
其中表示第位(从左至右)身份证号码值,表示权重系数,计算公式为。该权重系数是已知的,如表2-2所示。
表2-2 权重系数
假设有一个人是2032年5月19日出生,并在北京市海淀区上的户口,排在123位,那么前17位的号码是。,校验码。
细心的读者可能发现,模11的运算有一定的概率会出现值为10的结果,如果加入身份证号中,就会变成19位,比常规的18位数字多出了一位,这显然不符合身份证的设计要求。因此规定,当校验值等于10时,就用罗马数字“X”代替,使身份证号码位数不超过18位。这也是有些人的身份证号码最后一位是“X”的原因。
那么有了校验值后,如何确定身份证号码是否输入正确呢?校验公式如下:
输入身份证号码过程中,如果输入的号码全部正确,那么校验公式就会成立。而如果输错一位数,该校验公式则肯定不成立。
例2.4.6 检验身份证号330302204311117880是否符合要求。
解:根据身份证号信息可以知道,330302代表此人户口所在地,20431111代表此人是2043年11月11日出生的, 788代表此人是一名女性,且上户口的顺序是788 。那么就需要计算,如表2-3所示。
表2-3 身份证号码检验计算过程
根据校验公式(2-28),将求和并模11,可以得到:
校验公式(2-28)成立,因此该身份证号输入格式是正确的。
最后来探讨一下:为什么选择11作为模数,而不是7、8、9、10、12或者其他的数字呢?假设选择大于11的数字,如13 ,那么就会多出10、11、12这3个两位数的数字,为了符合身份证的长度,只能使用字母来代替,比如X、Y、Z。这并不符合身份证设计理念,增加了理解身份证数字信息的难度,很难对公众进行解释说明。如果是小于11的数字,如7 ,那么就会造成7、8、9这3个数字的“浪费”。现在看来, 10这个数字非常合适,不但没有数字浪费,还可以避免出现“X”这样的字母。但为什么不选择10作为模数呢?
首要原因是, 10是一个合数。上面提到,输错一位数,校验公式(2-28)肯定不成立。满足这个条件的前提是模数是一个素数。在例2.4.6中,,如果模数是10 ,那么。假设身份证号填错一位数,填成了330302204311117830 ,那么。在模10的运算下,它们的值都为3 ,通过了验证,但实际上是错误的。因此素数11显然是比合数10更为合适的选择。
然而,即使选择11作为模数,依然有可能在身份证号填写错误的情况下通过验证。例如身份证号填错的不是一位数,而是两位数,该组身份证号就有可能通过校验公式的校验。在例2.4.6中,如果填写成330302204311117530 ,此时,就通过了验证。不过由于错误发生的概率不高,因此被视为在可容忍的范围内。同时配合其他方式,如人脸识别、指纹识别进行再次校验,双管乃至多管齐下,便可确保个人身份的精确性和唯一性。