阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle 关于身份证校验规则详细说明(附有代码复制可执行)

116次阅读
没有评论

共计 4661 个字符,预计需要花费 12 分钟才能阅读完成。

身份证号码组成

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。可以判定这是一个合格的身份证号码。

CREATE OR REPLACE PROCEDURE PRC_身份证校验(ID_NUMBER    IN VARCHAR2, – 身份证号的输入
                                      ID_SEX        OUT VARCHAR2, – 性别
                                      ID_AGE        OUT NUMBER, – 年龄
                                      ID_BRITHDAY  OUT DATE, – 出生时间
                                      ID_NUMBER_END OUT VARCHAR2, – 最后校验的身份证
                                      ID_CODE      OUT NUMBER,
                                      ID_ERROR      OUT VARCHAR2) IS

  –15 位身份证号组成:
  – 省份 (2 位) 市(2 位)区 [县](2 位) 年(2 位)月 (2 位) 日(2 位)+ 3 位序列号 [奇数给男性 / 偶数给女性]

  –18 位身份证号组成:
  – 省份 (2 位) 市(2 位)区 [县](2 位) 年(4 位)月 (2 位) 日(2 位)+ 2 位序列号 + 1 位性别[奇数男 / 偶数女]+ 1 位校验码

  –ID_CODE 返回值分别为 1、-1、-2、-3、- 4 五类信息,负值表示身份证信息有误
  – 返回 1:表示身份证正确。
  – 返回 -1:表示系统错误,一般不会出现这个值。
  – 返回 -2:表示身份证位数有误。
  – 返回 -3:表示出生日期有误或者身份证含有不正确的信息。
  – 返回 -4:表示身份证最后一位校验位有误。

  – 声明数组变量
  – 声明 N 数组 用于存放身份证系数(加权因子)7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2
  TYPE N IS VARRAY(18) OF INTEGER;
  – 声明 S 数组 用于存放求 MOD 得的余数 ’1′,’0′,’X’,’9′,’8′,’7′,’6′,’5′,’4′,’3′,’2′
  TYPE S IS VARRAY(11) OF VARCHAR2(11);
  I            INTEGER;
  ID_MONTH    NUMBER; – 记录身份证上的月份
  ID_DAY      NUMBER; – 记录身份证上的日期
  JQYZ_N      N; – 将数组 N 的值赋予 JQYZ_N(校验因子)
  YS_S        S; – 将数组 S 的值赋予 YS_S(校验余数) 
  ID_SUM      INTEGER; – 身份证号分别乘以加权因子的总和
  ID_TMP_15_18 VARCHAR2(18); – 存储 15 位身份证转 18 位身份证年龄前 +19
  ID_SUM_MOD  VARCHAR2(2); – 存储加权因子总和 MOD11 取余数,得到身份证最后一位检验位
BEGIN
  ID_CODE  := 1;
  ID_ERROR := NULL;
  ID_DAY  := 0;
  ID_MONTH := 0;
  JQYZ_N  := N(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
  YS_S    := S(‘1’, ‘0’, ‘X’, ‘9’, ‘8’, ‘7’, ‘6’, ‘5’, ‘4’, ‘3’, ‘2’);
  ID_SUM  := 0;
  IF LENGTHB(ID_NUMBER) = 15 THEN
    BEGIN
      ID_TMP_15_18 := SUBSTRB(ID_NUMBER, 0, 6) || ’19’ ||
                      SUBSTRB(ID_NUMBER, 7); – 得到 18 位身份证
      – 循环计算身份证前 17 位和权加因子的相乘得到的总合
      FOR I IN 1 .. 17 LOOP
        ID_SUM := ID_SUM +
                  TO_NUMBER(SUBSTRB(ID_TMP_15_18, I, 1)) * JQYZ_N(I);
      END LOOP;
      – 将得到的总合除以 11 得到一个余数,余数对应相应值
      ID_SUM_MOD := YS_S(MOD(ID_SUM, 11) + 1);
      – 性别取值
      SELECT DECODE(MOD(TO_NUMBER(SUBSTRB(ID_NUMBER, 15, 1)), 2),
                    0,
                    ‘ 女 ’,
                    ‘ 男 ’)
        INTO ID_SEX
        FROM DUAL;
      – 出生时间取值
      ID_MONTH := TO_NUMBER(SUBSTRB(ID_TMP_15_18, 11, 2));
      ID_DAY  := TO_NUMBER(SUBSTRB(ID_TMP_15_18, 13, 2));
      IF (ID_MONTH > 0) AND (ID_MONTH < 13) THEN
        IF (ID_DAY > 0) AND (ID_DAY <= 31) THEN
          BEGIN
            ID_BRITHDAY := TO_DATE(SUBSTRB(ID_TMP_15_18, 7, 8), ‘YYYYMMDD’);
          EXCEPTION
            WHEN OTHERS THEN
              ID_CODE  := -1;
              ID_ERROR := ‘ 出生时间格式有误,请核实。’;
          END;
        ELSE
          ID_CODE  := -3;
          ID_ERROR := ‘ 您输入日(‘ || ID_DAY || ‘) 格式不符合要求 (1-31 号)’;
        END IF;
      ELSE
        ID_CODE  := -3;
        ID_ERROR := ‘ 您输入月(‘ || ID_MONTH || ‘) 格式不符合要求 (1-12 月份)’;
      END IF;
      – 计算年龄
      ID_AGE := TRUNC(MONTHS_BETWEEN(SYSDATE, ID_BRITHDAY) / 12);
      – 得出最后身份证号
      ID_NUMBER_END := ID_TMP_15_18 || UPPER(ID_SUM_MOD);
    END;
  ELSIF LENGTHB(ID_NUMBER) = 18 THEN
    BEGIN
      – 循环计算身份证前 17 位和权加因子的相乘得到的总合
      FOR I IN 1 .. 17 LOOP
        ID_SUM := ID_SUM + TO_NUMBER(SUBSTRB(ID_NUMBER, I, 1)) * JQYZ_N(I);
      END LOOP;
      – 将得到的总合除以 11 得到一个余数,余数对应相应值
      ID_SUM_MOD := YS_S(MOD(ID_SUM, 11) + 1);
      IF UPPER(SUBSTRB(ID_NUMBER, 18, 1)) != upper(ID_SUM_MOD) THEN
        ID_CODE  := -4;
        ID_ERROR := ‘ 身份证最后一位校验位有误, 应为(‘ || ID_SUM_MOD || ‘)’;
      END IF;
      – 性别取值
      SELECT DECODE(MOD(TO_NUMBER(SUBSTRB(ID_NUMBER, 17, 1)), 2),
                    0,
                    ‘ 女 ’,
                    ‘ 男 ’)
        INTO ID_SEX
        FROM DUAL;
      – 出生时间取值
      ID_MONTH := TO_NUMBER(SUBSTRB(ID_NUMBER, 11, 2));
      ID_DAY  := TO_NUMBER(SUBSTRB(ID_NUMBER, 13, 2));
      IF (ID_MONTH > 0) AND (ID_MONTH < 13) THEN
        IF (ID_DAY > 0) AND (ID_DAY <= 31) THEN
          BEGIN
            ID_BRITHDAY := TO_DATE(SUBSTRB(ID_NUMBER, 7, 8), ‘YYYYMMDD’);
          EXCEPTION
            WHEN OTHERS THEN
              ID_CODE  := -1;
              ID_ERROR := ‘ 出生时间格式有误,请核实。’;
          END;
        ELSE
          ID_CODE  := -3;
          ID_ERROR := ‘ 您输入日(‘ || ID_DAY || ‘) 格式不符合要求 (1-31 号)’;
        END IF;
      ELSE
        ID_CODE  := -3;
        ID_ERROR := ‘ 您输入月(‘ || ID_MONTH || ‘) 格式不符合要求(1-12 月份)’;
      END IF;
      – 计算年龄
      ID_AGE := TRUNC(MONTHS_BETWEEN(SYSDATE, ID_BRITHDAY) / 12);
      – 得出最后身份证号
      ID_NUMBER_END := substrb(ID_NUMBER, 1, 17) || upper(ID_SUM_MOD);
    END;
  ELSE
    ID_CODE  := -2;
    ID_ERROR := ‘ 该身份证号:’ || ID_NUMBER || ‘ 不符合要求 ’;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    ID_CODE  := -1;
    ID_ERROR := ‘ 系统发生未知错误 ’; – 一般不会发生该错误
END PRC_身份证校验;

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计4661字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中