php中文网最新课程
每日17点准时技术干货分享
互联网机构对身份证验证的需要越来越多,然而普通的小机构是没法对接公安分部的身份认证系统的。几乎都是在网上买有些大的互联网机构的有些认证服务。即使是便宜有些的认证价格亦达到了10万次/万元。亦便是一角钱一次了,还是挺贵哈。因此为了减少机构的开支,咱们在拿到用户提交的身份证信息去认证前应该自己先检验一下身份证的格式,倘若连最基本的身份证格式就不满足的话,咱们完全能够直接驳回,不必走接下来的花钱认证流程了,况且亦能够创立一个用户身份证表,把每次认证经过的数据存起来,以后每次都先从自己系统里的用户身份证表查找,查不到再去走认证流程,最大化节省机构开支。这儿供给一个初步验证身份证格式的PHP身份证验证类。该类只供给一个静态办法isValid接口,运用起来亦很简单,只需要运用IdentityCard::isValid就可验证。能够放到自己项目中当做工具类。该办法能够同期验证15位的老身份证和18位的新身份证格式PHP版本: >=7.0.0注:倘若PHP版本小于7.0版本只需要把类中办法的参数限制取消掉就可运用。class IdentityCard{ /** * 校验身份证号是不是合法 * @param string $num 待校验的身份证号 * @return bool */ public static function isValid(string $num){ //老身份证长度15位,新身份证长度18位 $length = strlen($num); if ($length == 15) { //倘若是15位身份证 //15位身份证无字母 if (!is_numeric($num)) { return false; } // 省市县(6位) $areaNum = substr($num, 0, 6); // 出生年月(6位) $dateNum = substr($num, 6, 6); } else if ($length == 18) { //倘若是18位身份证 //基本格式校验 if (!preg_match(/^\d{17}[0-9xX]$/, $num)) { return false; } // 省市县(6位)$areaNum = substr($num,0, 6); // 出生年月日(8位) $dateNum = substr($num, 6, 8); } else { //假身份证 return false; } //验证地区 if (!self::isAreaCodeValid($areaNum)) { return false; } //验证日期 if (!self::isDateValid($dateNum)) { return false; } //验证最后一位 if (!self::isVerifyCodeValid($num)) { return false; } return true; } /** * 省市自治区校验 * @paramstring $area 省、直辖市代码 * @return bool */ private static function isAreaCodeValid(string $area) { $provinceCode = substr($area, 0, 2); // 按照GB/T2260—999,省市代码11到65 if (11<= $provinceCode && $provinceCode <=65) { return true; } else { return false; } } /** * 验证出生日期合法性 * @param string $date 日期 * @return bool */ private static function isDateValid(string $date) { if (strlen($date) == 6) { //15位身份证号无年份,这儿拼上年份 $date = 19.$date; } $year = intval(substr($date, 0, 4)); $month = intval(substr($date, 4, 2));$day = intval(substr($date,6, 2)); //日期基本格式校验 if (!checkdate($month, $day, $year)) { return false; } //日期格式正确,然则规律存在问题(如:年份大于当前年) $currYear = date(Y); if($year > $currYear) { return false; } return true; } /** * 验证18位身份证最后一位 * @param string $num 待校验的身份证号 * @return bool */ private static function isVerifyCodeValid(string $num){ if(strlen($num) ==18) { $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; $tokens = [1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2]; $checkSum = 0; for ($i = 0; $i < 17; $i++) {$checkSum += intval($num{$i}) * $factor[$i]; } $mod = $checkSum % 11; $token = $tokens[$mod]; $lastChar = strtoupper($num{17}); if ($lastChar != $token) { return false; } } return true; }}
运用示例: // 测试$num = 33071919610920021X;if (IdentityCard::isValid($num)) { echo 身份证格式正确;} else { echo 身份证格式不正确;}
下面是身份证编码各个部分的含义: //=============新的18位身份证号码各位的含义:=======================//1-2位省、自治区、直辖市代码;11-65//3-4位地级市、盟、自治州代码;//5-6位县、县级市、区代码;//7-14位出生年月日,例如19670401表率1967年4月1日;//15-17位为次序号,其中17位男为单数,女为双数;//18位为校验码,0-9和X,由公式随机产生。//举例://130503 19670401 0012这个身份证号的含义: 13为河北,05为邢台,03为桥西区,出生日期为1967年4月1日,次序号为001,2为验证码//===========15位身份证号码各位的含义:=======================//1-2位省、自治区、直辖市代码;//3-4位地级市、盟、自治州代码;//5-6位县、县级市、区代码;//7-12位出生年月日,例如670401表率1967年4月1日,这是和18位号码的第1个区别;//13-15位为次序号,其中15位男为单数,女为双数;//与18位身份证号的第二个区别:没有最后一位的验证码。//举例://130503 670401 001的含义; 13为河北,05为邢台,03为桥西区,出生日期为1967年4月1日,次序号为001。
-END-
▼请点击下方:“阅读原文”,在线查看所有文案内容!
|