验证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