Oracle 身份證號碼校驗

2021-06-11 18:55:26 字數 3307 閱讀 9546

今天來了身份證校驗的需求,想在oracle中校驗後將錯誤資料查詢出來。於是我在網上查到了身份證校驗的oracle函式。但是發現一些正確的身份證號也未校驗通過!後來經過千辛萬苦的努力終於發現了,網上給的函式中判斷是否是閏年的 substrb 函式應該從第7為開始擷取,而不是第6位!!還有要注意最後一位校驗位的大小寫轉換後再做比較!坑爹啊!坑死我了!

create or replace function f_checkidcard (p_idcard in varchar2)

return int is v_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,';

begin

case lengthb(p_idcard)

when 15 then -- 15位         

if instrb(v_areacode, substr (p_idcard, 1, 2) || ',') = 0 then

return 1;

end if;

if mod (to_number (substrb (p_idcard, 7, 2)) + 1900, 400) = 0 or ( mod (to_number (substrb (p_idcard, 7, 2)) + 1900, 100) <> 0 and mod (to_number (substrb (p_idcard, 7, 2)) + 1900, 4) = 0 ) then -- 閏年

v_regstr := '^[1-9][0-9][0-9]((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]$';

else

v_regstr := '^[1-9][0-9][0-9]((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]$';

end if;           

if regexp_like (p_idcard, v_regstr) then

return 0;

else

return 1;

end if;

when 18 then -- 18位

if instrb (v_areacode, substrb (p_idcard, 1, 2) || ',') = 0 then

return 1;

end if;

if mod (to_number (substrb (p_idcard, 7, 4)), 400) = 0 or ( mod (to_number (substrb (p_idcard, 7, 4)), 100) <> 0 and mod (to_number (substrb (p_idcard, 7, 4)), 4) = 0 ) then -- 閏年

v_regstr :='^[1-9][0-9]19[0-9]((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][0-9xx]$';

else

v_regstr :='^[1-9][0-9]19[0-9]((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][0-9xx]$';

end if;

if regexp_like (p_idcard, v_regstr) then

v_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))then

return 0;

else

return 1;

end if;

else

return 1;

end if;

else         

return 1; -- 身份證號碼位數不對   

end case;

exception   

when others then

return 1;

end f_checkidcard;

身份證號碼校驗

中國居民身份證號碼編碼規則 中國居民身份證校驗碼演算法 都包含 author liuwei date 2020 11 19 身份證校驗工具 public class idnumutil 定義判別使用者身份證號的正規表示式 15位或者18位,最後一位可以為字母 string regularexpres...

JS校驗身份證號碼

function isidcardno num d 0 9 x test num 驗證前2位,城市符合 var acity if acity parseint num.substr 0,2 null alert 城市 acity parseint num.substr 0,2 下面分別分析出生日期和...

身份證號碼

每乙個人自出生後都會有乙個身份證號碼。根據我國有關部門規定,公民身份號碼是特徵組合碼,由十七位數字本體碼和一位數字校驗碼組成。排列順序從左至右依次為 六位數字位址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。居民身份證是國家法定的證明公民個人身份的有效證件。例如 對於身份證號碼330719...