Mysql自定義函數:身份證號碼的真實性判定

業務過程中,遇到了身份證判斷是否有效的問題。如能連接公安系統進行身份證判斷,自然是最準確的,但是這對普通碼農來講是不現實的。

現根據大陸身份證號碼規律,自己寫判斷規則,利用正則表達式來判斷給定的字符串是否是近似一個有效的身份證號碼。並將代碼封裝爲一個Mysql函數,方便代碼複用。

注意:本代碼所用規則根據一代、二代身份證的數字規律進行建立,只能近似保證號碼判斷的準確性、排除大多數錄入數據不規則的的情況,但針對少數符合規則但屬於無效的情況,這裏無法判斷。

廢話少說,直接上碼:

DELIMITER $$

USE `analysis`$$

DROP FUNCTION IF EXISTS `is_ID_card`$$

CREATE DEFINER=`lws`@`%` FUNCTION `is_ID_card`(number VARCHAR(20)CHARSET utf8) RETURNS TINYINT(1)
BEGIN
	DECLARE flag BOOL DEFAULT FALSE;
	IF (LENGTH(number)=18 
	AND number REGEXP CONCAT('^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([1][0-4])|([6][1-6])|([7][1])|([8][1-2]))', -- 1、2位
	'(([0][0-9])|([1][0-9])|([2][0-9])|([3][0-9])|([4][0-3])|([5][1-3])|([8][2])|([9][0]|[1]|[9]))', -- 3、4位
	'(([0-3][0-9])|([4][0-4])|([5][1])|([8][1-9])|([9][0-9]))', -- 5、6位
	'(([1]([8]|[9])[0-9])|([2]([0]|[0-1])[0-9]))[0-9](0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[0-9]{3}([0-9]|X)') -- 後12位
	OR (LENGTH(number)=15 
	AND number REGEXP CONCAT('^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([1][0-4])|([6][1-6])|([7][1])|([8][1-2]))',
	'(([0][0-9])|([1][0-9])|([2][0-9])|([3][0-9])|([4][0-3])|([5][1-3])|([8][2])|([9][0]|[1]|[9]))',
	'(([0-3][0-9])|([4][0-4])|([5][1])|([8][1-9])|([9][0-9]))',
	'(0[1-9]|[1-9][0-9])(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[0-9]{3}')))
	THEN SET flag = TRUE;
	END IF;
	RETURN flag;
    END$$

DELIMITER ;

大家把上述代碼保存爲一個mysql函數,然後調用該函數即可。

使用方法:

SELECT is_ID_card('這裏輸入需要驗證的身份證號碼')

這裏分18位身份證號碼、15位身份證號碼兩種情況:

  • 它們前六位一致,都是省級代碼(前兩位)、地市級代碼(前4位)、縣區級代碼(前6位);
  • 出生年月日方面,18位身份證是形如1990XXXX的格式,而15位身份證是形如79XXXX的格式,也即後者省去了年份的前兩位;
  • 18位身份證最後一位是校驗碼,可爲數字或者X,而15位身份證沒有最後一位校驗碼。

值的注意的是,代碼中的正則表達式字符串由於過長,這裏使用了一個小竅門來進行換行顯示,以提高代碼可讀性:

先把原來的一個長正則表達式拆分爲幾個,再使用concat()函數連接起來,因爲concat()函數內部參數之間是可以任意換行的,所以就變相實現了原字符串的換行。這一點,在以後遇到字符串需要換行的時候可以使用。

* 原創文章,如需轉載請註明出處,謝謝合作!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章