龙空技术网

数据二三事 公民身份号码

发烧的小冰箱 181

前言:

眼前看官们对“oracle校验数字”大致比较注意,兄弟们都想要知道一些“oracle校验数字”的相关文章。那么小编同时在网上搜集了一些对于“oracle校验数字””的相关内容,希望各位老铁们能喜欢,看官们一起来了解一下吧!

公民身份号码可谓我们业务工作中最重要的一串号码了,可能也是我们每一个中国人最重要的一串号码。当然你非要说银行存款那串对你更重要那就是抬杠了。

公民身份号码有各种各样的讲法和称呼,像居民身份号码、身份证号码等等,但正规的标准叫法就是公民身份号码。因为在规定公民身份号码的国家标准《GB11643-1999》中明确指出公民身份号码的编码对象是具有中华人民共和国国籍的公民,所以叫居民身份号码明显就不对了。

在国标《GB11643-1999》中详细规定了这串数据的构成规则以及含义,在本文中简要的把里面的内容给大家讲一下。

公民身份号码是特征组合码,长度规定为十八位,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

什么是特征组合码?

就是这段数字是由不同能表现具体含义的数字组成的,像公民身份号码,我们可以直接从这串数字中读出它所代表人的所属地、年龄、性别等信息。与特征组合码相对的有序列码等。比如一串随机生成的序列数字,那它就不再包含任何特征。如果我们对每一个中国公民不重复地附一个序列码也是可行的,而且不暴露公民的具体特征。估计当年在定公民身份号码时也有过相关讨论,但可能种种因素促成了现在的公民身份号码方案。

下面开始逐位介绍这串数字,总的来说前六位是地址码,也就是你出生后上户口时所属户籍地的省市县三级代码,具体代码参见国标行政区划代码《GB/T2260》,行政区划代码后面我还会单独拿出来讲。接下来八位是出生年月,格式为yyyymmdd,这个好理解。再三位是顺序码,这个是在上户口时由户籍管理部门确定的,顺序码的奇数分配给男性,偶数分配给女性,也就是可以通过看第十七位的奇偶判断性别男女。我们可以计算出同一天理论上一个区县级户籍部门理论上可以给1000名公民上户口,其中男500,女500,按计算一个区县绝无一天超额的情况。

最后一位是检验码,就是用来校验整串数字是否准确的校验位。在十八位公民身份号码启动之前,标准采用的是十五位公民身份号码。十五位的构成如下:1-6位地址码、7-12位出生年月日,比如670401代表1967年4月1日、13-15位为顺序号,其中15位男为单数,女为双数。

我们看出十八位与十五的区别除了出生年月日多了年份的两位之外,就是加了一位检验码。检验码主要解决数据录入转录等过程中出现错误的问题,换一种说法就是防止瞎编号码。原来十五位号码的时候因为没有检验码,你可以随意编造公民身份号码,当然地址和出生日期得编的稍微合理,。但十八位的号码编造就不那么容易了。

检验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。具体公式如果你想看就是下图

如果你觉得头痛可以不看……

简单的说最后一位数字是由前十七位数字的加权和然后取11的余数得来的。数字对11取余数结果有10个(0、1、2、3、4、5、6、7、8、9、10),当然如果余数是10的话就超了位数,于是用罗马字符X来代替,在罗马字符里X就代表10的意思。罗马字符X也就是英文字母X(大写)。

有很多不了解的网友很新鲜地说我的身份号码最后一位是X哎,其实就是10(你并不是天选之子)。

有了公式就可以开搞了,比如说可以批量的把原来的十五位的公民身份号码升位成十八位的。先增加两位年份数字,然后根据这十七位计算出检验码附在后面就形成了新的十八位公民身份号码。还有就是可以用来检验一个身份号码在规则上是否合法,这个各类系统和网站上都植入了公民身份号码检验程序,这个程序是根据上述的公式编写的。这样当用户输入一个瞎编的号码或者号码输错时,系统会通过检验程序计算出号码不合法。

可是你有没有发现,这个公式是公开的,你可以利用这个公式自己批量编身份号码,这样校验程序就失效了。如果这个对你的要求太高,那么其实理论上你只要试11次就能编造一个合法的身份号码,因为公式最后是对11取余,所以你如果编好了前十七位,那么最后一位数字只要试11次就一定可以找到正确的校验码。

道高一尺魔高一丈啊。要真正检验一个身份号码的合法性,其实只能去看公安人口系统中到底有没有这个身份号码,或者是拿到实体的身份证件。这些问题有机会可以在其他文章中讲解,目前我的文章只关注数据层面。

话转过来,我们再来看检验公式,公式里最后是对11取余,结果导致身份号码最后一位出现了一个非数字字符X,那么这个字符对整体的号码有什么影响呢?可以想象如果公式里不是对11取余而是对10取余,那么最后一位就是纯数字了,整串号码也就是纯数字了。这里我能想到的最直接的影响就是数据的存储和计算。

如果身份号码是纯数字,那么我们在系统中就可以按照数值型对身份号码就行存储,如在ORACLE数据库中可以按照NUMBER类型对身份号码字段进行存储,那么一个18位的数字只需要约十个字节存储。而如果身份号码不是纯数字,那么只能按照字符型对其进行存储,如在ORACLE数据库中可以按照VCHAR类型对身份号码字段进行存储,那么一个18位号码则需要至少36个字节存储。当然在现在存储好像不是太大的问题。但在计算上,数值型数据明显比字符型数据要快的多。比如我们查询身份号码时,其实后台在进行计算,如果有索引的话,相当于先给数据进行排序,如果没有索引,那么就逐条进行比对,原则上都是对数据进行计算。显而易见数值型的身份号码必然要比字符型的身份号码要高效的多,引申开来,各种关联查询,比对分析也会快的更多。但我们现行的身份号码已经不能是数值型了,因为有字符X。(在这里,还要提醒下身份号码里的是大写的X,小写x是无效的)

身份号码不是一串纯数字,但它长得太像的,导致很多软件都误认为它是数字,比如EXCEL。在工作中你会发现,当你在EXCEL中输入身份号码或将文件中的身份号码导入到EXCEL中,EXCEL会把它自动转化为科学计数法,如下图

这就是EXCEL把这串号码当成了数字,也就是数值型。那么我们怎么解决这个问题呢,我们得把这一列设为文本型也就是字符型,那么导进来或输入的号码就不会出现这种问题了,如下图:

聊回到开头,为什么说公民身份号码是我们最重要的号码,因为它唯一表征了我们每一个具体的人,是不重复的。在之前可能由于各种原因导致有身份号码重号的情况,但经过多年的清理整改,现在基本已经能确保每人一个号码。那这个号码就是你的唯一标识,而且是终身不变的,你的名字、地址、手机号码、网络账号统统不是。很多业务的开展都是附在这串号码上的,如教育、医疗、社保、房产等等。这串号码就是数据世界的你,你的属性和活动也被这串号码刻画着。

由此我们也可以得出,我们业务工作中最终针对人的信息最终数据都要落到这串号码上。当然这当中还有好多工作要做,我们要把能够表明人员身份的数据映射到身份号码上来,如护照、手机号码、网络账号等等。这些内容在后面会跟大家进行探讨,谢谢!

标签: #oracle校验数字