mysql根据严格校验15位和18位身份证号是否有效的自定义函数

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

上一篇:chown命令


下一篇:javaScript系列 [39]-deepClone