说明:最近项目需求要对用户身份证的有效期验证,但向公安系统或者银联付费请求查询对应信息,
金额成本比较高,每次查询3-5元人民币成本较高,于是需要自行来处理有效期规则和防止有效期、
身份证号码等规则被篡改:
一、首先判断身份证有效期截止日期是否是“长期”,若为长期且当前年份减去身份证号码里出生日期年份>=46(岁)则直接当作未过期来处理(因为仅在年龄>=46时身份证有效期才可能会为“长期”);
二、若有效期截止日期不是长期,则继续和本地服务器当前时间判断,若有效期截止日期在本地服务器当前时间之前,返回过期:
三、若有效期截止日期在本地服务器当前时间之后,继续以下判断:
STEP1:系统根据“主卡证件有效起始日期”及“主卡证件有效截止日期”栏位的差值计算主卡人持有的是5年/10年/20年/长期/临时的身份证,记为值A
若“主卡证件有效截止日期”栏位值前4位-“主卡证件有效起始日期”栏位值前4位=5,则A=5;
若“主卡证件有效截止日期”栏位值前4位-“主卡证件有效起始日期”栏位值前4位=10,则A=10;
若“主卡证件有效截止日期”栏位值前4位-“主卡证件有效起始日期”栏位值前4位=20,则A=20;
若“主卡证件有效截止日期”栏位值前4位-“主卡证件有效起始日期”栏位值前4位〉20,则A=长期;
若“主卡证件有效截止日期”栏位值前4位-“主卡证件有效起始日期”栏位值前4位=0或=1,则A=0或=1;
STEP2:系统根据主卡人的“出生日期”及“主卡证件有效起始日期”计算主卡人办理身份证时的年龄(周岁),记为值B
B=(“主卡证件有效起始日期”栏位值—“出生日期”栏位值)/10000后的整数部分 ->(如果直接取到年份:年份-年份不用出10000)
STEP3:若值A与值B不满足以下关系,则有效期无效;
当A=5时,B<16;
当A=10时,16≤B≤25;
当A=20时,26≤B≤45;
当A=长期时,B>=46;
当A=0或A=1时,B可为任意值;
STEP4:当A≠5且A≠10且A≠20且A≠长期且A≠1且A≠0时,则有效期无效;
STEP5:A=5或A=10或A=20时,若“主卡证件有效起始日期”和“主卡证件有效截止日期”月日不是一一匹配,则有效期无效。
四:代码封装
public function verifyEffectiveTime($cardNum, $startTime, $endTime)
{
$ret = false;
$startMonthMDay = substr($startTime, 5);
$endtMonthMDay = substr($endTime, 5);
$compareMonthDay = ($startMonthMDay == $endtMonthMDay);
$effectiveStartTime = substr($startTime, 0, 4);
$variableOne = substr($endTime, 0, 4) - $effectiveStartTime;
$getBirthDay = IdCard::getBirthDay($cardNum);
$birthYear = substr($getBirthDay, 0, 4);
$variableTwo = $effectiveStartTime - $birthYear;
if ($variableOne == 5) {
if (($variableTwo < 16) && $compareMonthDay) {
$ret = true;
}
} elseif ($variableOne == 10) {
if ((16 <= $variableTwo && $variableTwo <= 25) && $compareMonthDay) {
$ret = true;
}
} elseif ($variableOne == 20) {
if ((26 <= $variableTwo && $variableTwo <= 45) && $compareMonthDay) {
$ret = true;
}
} elseif ($variableOne > 20) {//长期
if ($variableTwo >= 46) {
$ret = true;
}
} elseif ($variableTwo == 0 || $variableTwo == 1) {
//则A=0或=1,$variableTwo可以为任意值
$ret = true;
} else {
$ret = false;
}
return $ret;
}