您的位置:首页 > 数据库 > Oracle

Oracle中身份证校验函数

2015-08-07 10:45 525 查看
居民身份证号码,根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 居民身份证是国家法定的证明公民个人身份的有效证件。
  地址码
  (身份证前六位)表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
  生日期码
  (身份证第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。
  顺序码
  (身份证第十五位到十七位)为同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。
  校验码
  (身份证最后一位)是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且我国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
身份证号校验位算法:           1:把前17位号码从第高位到低位与下列17个数字分别相乘求和(N):               『2,4,8,5,10,9,7,3,6,1,2,4,8,5,10,9,7』                比如身份证号码为:C1C2C3……C16C17                则N=C17×2+C16×4+……+C1×7;           2:将N除以11取余数R,根据余数计算校验位T:                1)如果R=0,则T=1;如果R=1,则T=0;如果R=2,则T=X;                2)如果R=3,则T=9;如果R=4,则T=8;依此类推……;如果R=10,则T=2
CREATE OR REPLACE FUNCTION fn_checkidcard (p_idcard IN VARCHAR2) RETURN INTISv_regstr      VARCHAR2 (2000);v_sum         NUMBER;v_mod         NUMBER;v_checkcode   CHAR (11)       := '10X98765432';v_checkbit    CHAR (1);v_areacode    VARCHAR2 (2000) := '11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,';BEGINCASE LENGTHB (p_idcard)WHEN 15THEN                                                            -- 15位IF INSTRB (v_areacode, SUBSTR (p_idcard, 1, 2) || ',') = 0 THENRETURN 0;END IF;IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 400) = 0OR(MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 100) <> 0ANDMOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 4) = 0)THEN                                                          -- 闰年v_regstr :='^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$';ELSEv_regstr :='^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$';END IF;IF REGEXP_LIKE (p_idcard, v_regstr) THENRETURN 1;ELSERETURN 0;END IF;WHEN 18THEN                                                             -- 18位IF INSTRB (v_areacode, SUBSTRB (p_idcard, 1, 2) || ',') = 0 THENRETURN 0;END IF;IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 400) = 0OR(MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 100) <> 0ANDMOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 4) = 0)THEN                                                          -- 闰年v_regstr :='^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$';ELSEv_regstr :='^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$';END IF;IF REGEXP_LIKE (p_idcard, v_regstr) THENv_sum :=(  TO_NUMBER (SUBSTRB (p_idcard, 1, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 11, 1)))* 7+   (  TO_NUMBER (SUBSTRB (p_idcard, 2, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 12, 1)))* 9+   (  TO_NUMBER (SUBSTRB (p_idcard, 3, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 13, 1)))* 10+   (  TO_NUMBER (SUBSTRB (p_idcard, 4, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 14, 1)))* 5+   (  TO_NUMBER (SUBSTRB (p_idcard, 5, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 15, 1)))* 8+   (  TO_NUMBER (SUBSTRB (p_idcard, 6, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 16, 1)))* 4+   (  TO_NUMBER (SUBSTRB (p_idcard, 7, 1))+ TO_NUMBER (SUBSTRB (p_idcard, 17, 1)))* 2+ TO_NUMBER (SUBSTRB (p_idcard, 8, 1)) * 1+ TO_NUMBER (SUBSTRB (p_idcard, 9, 1)) * 6+ TO_NUMBER (SUBSTRB (p_idcard, 10, 1)) * 3;v_mod := MOD (v_sum, 11);v_checkbit := SUBSTRB (v_checkcode, v_mod + 1, 1);IF v_checkbit = upper(substrb(p_idcard,18,1)) THENRETURN 1;ELSERETURN 0;END IF;ELSERETURN 0;END IF;ELSERETURN 0;                                      -- 身份证号码位数不对END CASE;EXCEPTIONWHEN OTHERSTHENRETURN 0;END fn_checkidcard;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: