zoukankan      html  css  js  c++  java
  • Oracle 关于身份证校验规则详细说明(附有代码复制可执行)

    身份证号码组成

    15位身份证号组成:

      省份(2)(2)[](2)(2)(2)(2)+3序列号 [奇数给男性/偶数给女性]

    18位身份证号组成:

    省份(2)(2)[](2)(4)(2)(2)+2位序列号+1位性别[奇数给男性/偶数给女性]+1位校验码

    注意:

    1)(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。

    2)(身份证号码第十五位到十七位)地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。

    3)(身份证号码最后一位)是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,主要是为了校验计算机输入公民身份证号码的前17位数字是否正确,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且中国的计算机用用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。

    三、校验码的计算方法

    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、通过上面得知如果余数是2,身份证的最后一位号码就是罗马数字x。如果余数是10,就会在身份证的第18位数字上出现的是2。

    例如:某男性的身份证号码 我们要看看这个身份证是不是合法的身份证。45010119890620001X仅测试使用

    首先我们得出前17位的乘积和是244,然后用244除以11得出的结果是17+2/11,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的是罗马数字X。可以判定这是一个合格的身份证号码。

      1 CREATE OR REPLACE PROCEDURE PRC_身份证校验(ID_NUMBER     IN VARCHAR2, --身份证号的输入
      2                                       ID_SEX        OUT VARCHAR2, --性别
      3                                       ID_AGE        OUT NUMBER, --年龄
      4                                       ID_BRITHDAY   OUT DATE, --出生时间
      5                                       ID_NUMBER_END OUT VARCHAR2, --最后校验的身份证
      6                                       ID_CODE       OUT NUMBER,
      7                                       ID_ERROR      OUT VARCHAR2) IS
      8 
      9   --15位身份证号组成:
     10   --省份(2位)市(2位)区[县](2位)年(2位)月(2位)日(2位)+3位序列号 [奇数给男性/偶数给女性]
     11 
     12   --18位身份证号组成:
     13   --省份(2位)市(2位)区[县](2位)年(4位)月(2位)日(2位)+2位序列号+1位性别[奇数男/偶数女]+1位校验码 
     14 
     15   --ID_CODE返回值分别为1、-1、-2、-3、-4五类信息,负值表示身份证信息有误
     16   --返回1:表示身份证正确。
     17   --返回-1:表示系统错误,一般不会出现这个值。
     18   --返回-2:表示身份证位数有误。
     19   --返回-3:表示出生日期有误或者身份证含有不正确的信息。
     20   --返回-4:表示身份证最后一位校验位有误。
     21 
     22   --声明数组变量
     23   --声明N数组 用于存放身份证系数(加权因子)7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2
     24   TYPE N IS VARRAY(18) OF INTEGER;
     25   --声明S数组 用于存放求MOD得的余数'1','0','X','9','8','7','6','5','4','3','2'
     26   TYPE S IS VARRAY(11) OF VARCHAR2(11);
     27   I            INTEGER;
     28   ID_MONTH     NUMBER; --记录身份证上的月份
     29   ID_DAY       NUMBER; --记录身份证上的日期
     30   JQYZ_N       N; --将数组N的值赋予JQYZ_N(校验因子)
     31   YS_S         S; --将数组S的值赋予YS_S(校验余数)   
     32   ID_SUM       INTEGER; --身份证号分别乘以加权因子的总和
     33   ID_TMP_15_18 VARCHAR2(18); --存储15位身份证转18位身份证年龄前+19
     34   ID_SUM_MOD   VARCHAR2(2); --存储加权因子总和MOD11取余数,得到身份证最后一位检验位
     35 BEGIN
     36   ID_CODE  := 1;
     37   ID_ERROR := NULL;
     38   ID_DAY   := 0;
     39   ID_MONTH := 0;
     40   JQYZ_N   := N(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
     41   YS_S     := S('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
     42   ID_SUM   := 0;
     43   IF LENGTHB(ID_NUMBER) = 15 THEN
     44     BEGIN
     45       ID_TMP_15_18 := SUBSTRB(ID_NUMBER, 0, 6) || '19' ||
     46                       SUBSTRB(ID_NUMBER, 7); --得到18位身份证
     47       --循环计算身份证前17位和权加因子的相乘得到的总合
     48       FOR I IN 1 .. 17 LOOP
     49         ID_SUM := ID_SUM +
     50                   TO_NUMBER(SUBSTRB(ID_TMP_15_18, I, 1)) * JQYZ_N(I);
     51       END LOOP;
     52       --将得到的总合除以11得到一个余数,余数对应相应值
     53       ID_SUM_MOD := YS_S(MOD(ID_SUM, 11) + 1);
     54       --性别取值
     55       SELECT DECODE(MOD(TO_NUMBER(SUBSTRB(ID_NUMBER, 15, 1)), 2),
     56                     0,
     57                     '',
     58                     '')
     59         INTO ID_SEX
     60         FROM DUAL;
     61       --出生时间取值
     62       ID_MONTH := TO_NUMBER(SUBSTRB(ID_TMP_15_18, 11, 2));
     63       ID_DAY   := TO_NUMBER(SUBSTRB(ID_TMP_15_18, 13, 2));
     64       IF (ID_MONTH > 0) AND (ID_MONTH < 13) THEN
     65         IF (ID_DAY > 0) AND (ID_DAY <= 31) THEN
     66           BEGIN
     67             ID_BRITHDAY := TO_DATE(SUBSTRB(ID_TMP_15_18, 7, 8), 'YYYYMMDD');
     68           EXCEPTION
     69             WHEN OTHERS THEN
     70               ID_CODE  := -1;
     71               ID_ERROR := '出生时间格式有误,请核实。';
     72           END;
     73         ELSE
     74           ID_CODE  := -3;
     75           ID_ERROR := '您输入日(' || ID_DAY || ')格式不符合要求(1-31号)';
     76         END IF;
     77       ELSE
     78         ID_CODE  := -3;
     79         ID_ERROR := '您输入月(' || ID_MONTH || ')格式不符合要求(1-12月份)';
     80       END IF;
     81       --计算年龄
     82       ID_AGE := TRUNC(MONTHS_BETWEEN(SYSDATE, ID_BRITHDAY) / 12);
     83       --得出最后身份证号
     84       ID_NUMBER_END := ID_TMP_15_18 || UPPER(ID_SUM_MOD);
     85     END;
     86   ELSIF LENGTHB(ID_NUMBER) = 18 THEN
     87     BEGIN
     88       --循环计算身份证前17位和权加因子的相乘得到的总合
     89       FOR I IN 1 .. 17 LOOP
     90         ID_SUM := ID_SUM + TO_NUMBER(SUBSTRB(ID_NUMBER, I, 1)) * JQYZ_N(I);
     91       END LOOP;
     92       --将得到的总合除以11得到一个余数,余数对应相应值
     93       ID_SUM_MOD := YS_S(MOD(ID_SUM, 11) + 1);
     94       IF UPPER(SUBSTRB(ID_NUMBER, 18, 1)) != upper(ID_SUM_MOD) THEN
     95         ID_CODE  := -4;
     96         ID_ERROR := '身份证最后一位校验位有误,应为(' || ID_SUM_MOD || ')';
     97       END IF;
     98       --性别取值
     99       SELECT DECODE(MOD(TO_NUMBER(SUBSTRB(ID_NUMBER, 17, 1)), 2),
    100                     0,
    101                     '',
    102                     '')
    103         INTO ID_SEX
    104         FROM DUAL;
    105       --出生时间取值
    106       ID_MONTH := TO_NUMBER(SUBSTRB(ID_NUMBER, 11, 2));
    107       ID_DAY   := TO_NUMBER(SUBSTRB(ID_NUMBER, 13, 2));
    108       IF (ID_MONTH > 0) AND (ID_MONTH < 13) THEN
    109         IF (ID_DAY > 0) AND (ID_DAY <= 31) THEN
    110           BEGIN
    111             ID_BRITHDAY := TO_DATE(SUBSTRB(ID_NUMBER, 7, 8), 'YYYYMMDD');
    112           EXCEPTION
    113             WHEN OTHERS THEN
    114               ID_CODE  := -1;
    115               ID_ERROR := '出生时间格式有误,请核实。';
    116           END;
    117         ELSE
    118           ID_CODE  := -3;
    119           ID_ERROR := '您输入日(' || ID_DAY || ')格式不符合要求(1-31号)';
    120         END IF;
    121       ELSE
    122         ID_CODE  := -3;
    123         ID_ERROR := '您输入月(' || ID_MONTH || ')格式不符合要求(1-12月份)';
    124       END IF;
    125       --计算年龄
    126       ID_AGE := TRUNC(MONTHS_BETWEEN(SYSDATE, ID_BRITHDAY) / 12);
    127       --得出最后身份证号
    128       ID_NUMBER_END := substrb(ID_NUMBER, 1, 17) || upper(ID_SUM_MOD);
    129     END;
    130   ELSE
    131     ID_CODE  := -2;
    132     ID_ERROR := '该身份证号:' || ID_NUMBER || ' 不符合要求';
    133   END IF;
    134 EXCEPTION
    135   WHEN OTHERS THEN
    136     ID_CODE  := -1;
    137     ID_ERROR := '系统发生未知错误'; --一般不会发生该错误
    138 END PRC_身份证校验;
  • 相关阅读:
    区块链是怎么运行的
    区块链技术到底是什么鬼(二)
    区块链技术到底是什么鬼(一)
    关于SetTimer间隔小于OmTimer执行时间的问题
    区块链
    浏览器原生 form 表单POST 数据的两种方式
    动态调用dll遇到的问题
    转-tcp建立和释放详解
    浏览器使用ActiveX控件
    C可变参数函数 实现
  • 原文地址:https://www.cnblogs.com/ljs05/p/7153879.html
Copyright © 2011-2022 走看看