验证18位身份证有效性的规则:
1、长度;
2、区划编码;
3、出生日期;
4、最后一位验证;
第一步:对身份证做去空处理;
第二步:对15位身份证号进行验证;
第三步:对18位身份证进行验证;
最后,可根据完成的函数进行测试,如有问题,还请指正,谢谢哦~
CREATE DEFINER=`root`@`localhost` FUNCTION `check_idcard`(sfzh varchar(32)) RETURNS varchar(32) CHARSET utf8 READS SQL DATA DETERMINISTIC COMMENT '身份证号校验' BEGIN DECLARE v_flag VARCHAR(32) DEFAULT ''; DECLARE v_sum VARCHAR(32) DEFAULT ''; DECLARE v_mod VARCHAR(32) DEFAULT ''; DECLARE i_flag VARCHAR(32) DEFAULT ''; # 去除空格 SET sfzh = REPLACE(sfzh,' ',''); # 长度不等于18或者15为空 IF LENGTH(sfzh) <> 18 THEN IF LENGTH(sfzh) <> 15 THEN RETURN ''; END IF; END IF; # 判断区划代码前两位 IF SUBSTRING(sfzh,1,2) NOT IN (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,83) THEN RETURN '0'; END IF; #判断15位身份证号 IF LENGTH(sfzh) = 15 THEN IF ((SUBSTRING(sfzh,7,2)+1900)%4=0 AND (SUBSTRING(sfzh,7,2)+1900)%100<>0) OR ((SUBSTRING(sfzh,7,2)+1900)%400=0) THEN IF (sfzh REGEXP '[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}$') OR (sfzh REGEXP '[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}$') THEN #SET v_flag = '1'; RETURN sfzh; ELSE #SET v_flag = '0'; RETURN ''; END IF; END IF; END IF; # 判断18位身份证号 IF LENGTH(sfzh) = 18 THEN # 判断年份前两位 IF SUBSTRING(sfzh,7,2) NOT BETWEEN 19 AND 21 THEN RETURN '0'; END IF; # 判断月份 IF SUBSTRING(sfzh,11,2) NOT BETWEEN 01 AND 12 THEN RETURN '0'; END IF; # 判断31天日期 IF SUBSTRING(sfzh,11,2) IN (01,03,05,07,08,10,12) THEN IF SUBSTRING(sfzh,13,2) NOT BETWEEN 01 AND 31 THEN RETURN '0'; END IF; END IF; # 判断30天日期 IF SUBSTRING(sfzh,11,2) IN (04,06,09,11) THEN IF SUBSTRING(sfzh,13,2) NOT BETWEEN 01 AND 30 THEN RETURN '0'; END IF; END IF; # 判断2月日期 IF SUBSTRING(sfzh,11,2)=02 THEN IF (SUBSTRING(sfzh,7,4)%4=0 AND SUBSTRING(sfzh,7,4)%100<>0) OR (SUBSTRING(sfzh,7,4)%400=0) THEN IF SUBSTRING(sfzh,13,2) NOT BETWEEN 01 AND 29 THEN RETURN '0'; END IF; ELSEIF SUBSTRING(sfzh,13,2) NOT BETWEEN 01 AND 28 THEN RETURN '0'; END IF; END IF; # 判断校验位 SET v_sum = (SUBSTRING(sfzh,1,1)*7) + (SUBSTRING(sfzh,2,1)*9) + (SUBSTRING(sfzh,3,1)*10) + (SUBSTRING(sfzh,4,1)*5) + (SUBSTRING(sfzh,5,1)*8) + (SUBSTRING(sfzh,6,1)*4) + (SUBSTRING(sfzh,7,1)*2) + (SUBSTRING(sfzh,8,1)*1) + (SUBSTRING(sfzh,9,1)*6) + (SUBSTRING(sfzh,10,1)*3) + (SUBSTRING(sfzh,11,1)*7) + (SUBSTRING(sfzh,12,1)*9) + (SUBSTRING(sfzh,13,1)*10) + (SUBSTRING(sfzh,14,1)*5) + (SUBSTRING(sfzh,15,1)*8) + (SUBSTRING(sfzh,16,1)*4) + (SUBSTRING(sfzh,17,1)*2); SET v_mod = v_sum % 11; IF v_mod = 0 THEN SET i_flag = '1'; END IF; IF v_mod = 1 THEN SET i_flag = '0'; END IF; IF v_mod = 2 THEN SET i_flag = 'X'; END IF; IF v_mod = 3 THEN SET i_flag = '9'; END IF; IF v_mod = 4 THEN SET i_flag = '8'; END IF; IF v_mod = 5 THEN SET i_flag = '7'; END IF; IF v_mod = 6 THEN SET i_flag = '6'; END IF; IF v_mod = 7 THEN SET i_flag = '5'; END IF; IF v_mod = 8 THEN SET i_flag = '4'; END IF; IF v_mod = 9 THEN SET i_flag = '3'; END IF; IF v_mod = 10 THEN SET i_flag = '2'; END IF; IF i_flag = SUBSTRING(sfzh,18,1) THEN #SET v_flag = '1'; return sfzh; ELSE #SET v_flag = '0'; RETURN ''; END IF; END IF; END