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;
相关文章推荐
- Oracle 导出、导入某用户所有数据(包括表、视图、存储过程...)
- tnsping是否可以证明Oracle数据库可用?
- oracle变量(2)
- oracle PL/SQL基础学习
- oracle initialization or shutdown in progress解决方法
- Oracle VM VirtualBox VBoxDD.Dll GetLastError=1790 错误处理方法
- Oracle 64bit 在redhat下内存如何调大
- oracle基本操作
- toad for oracle中文显示乱码
- toad for oracle中文显示乱码
- Oracle中触发器(2)
- Oracle层次查询
- Oracle 11g r2 linux centos 6.5 安装配置教程(多图超详细)
- 使用Oracle插入语法来插入多条记录
- ORACLE启动报错:ORA-16068:redo log file activation identifier mismatch
- oracle函数:instr
- mysql、sql server、oracle数据库分页查询及分析(操作手册)
- 免安装Oracle客户端使用PL/SQL连接Oracle
- Oracle初探(八)
- oracle查看表空间使用大小和扩展表空间