>  기사  >  백엔드 개발  >  PHP 확인 ID 카드 형식

PHP 확인 ID 카드 형식

angryTom
angryTom앞으로
2019-10-24 18:04:192805검색

인터넷 기업에서는 신분증 인증에 대한 요구가 늘어나고 있지만 일반 소규모 기업에서는 공안부의 신원 인증 시스템에 연결할 수 없습니다. 일부 대형 인터넷 회사의 거의 모든 인증 서비스는 온라인으로 구매됩니다. 더 저렴한 인증 가격도 100,000회/10,000위안에 이릅니다. 한 번에 1센트밖에 안 들지만 꽤 비쌉니다. 따라서, 회사의 비용 절감을 위해, 본인 인증을 위해 이용자가 제출한 신분증 정보를 받기 전, 신분증의 형식을 직접 확인하여야 하며, 가장 기본적인 신분증 형식이 만족스럽지 못한 경우에는 당사에서 직접 거부할 수 있습니다. 인증을 위해 돈을 쓰는 다음 과정을 거치지 않고도 사용자 ID 카드 테이블을 만들어 각 인증을 통과한 데이터를 저장할 수도 있습니다. 앞으로는 먼저 사용자 ID 카드 테이블을 직접 쿼리하게 됩니다. 시스템을 통해 매번 인증 프로세스를 진행하여 기업의 비용 절감을 극대화하세요.
신분증 형식에 대한 사전 검증을 위한 PHP 신분증 확인 수업입니다. 이 클래스는 사용이 매우 간단한 정적 메소드 isValid 인터페이스만 제공합니다. 확인하려면 IdentityCard::isValid만 사용하면 됩니다. 도구 클래스로 자신의 프로젝트에 넣을 수 있습니다. 이 방법을 사용하면 기존 신분증 15자리와 신규 신분증 형식 18자리를 동시에 확인할 수 있습니다. isValid接口,使用起来也很简单,只需要使用IdentityCard::isValid即可验证。可以放到自己项目中当做工具类。该方法可以同时验证15位的老身份证和18位的新身份证格式
PHP版本: >=7.0.0PHP 버전: >=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;
    }

    /**
     * 省市自治区校验
     * @param string $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 = &#39;19&#39;.$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(&#39;Y&#39;);
        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 = [&#39;1&#39;, &#39;0&#39;, &#39;X&#39;, &#39;9&#39;, &#39;8&#39;, &#39;7&#39;, &#39;6&#39;, &#39;5&#39;, &#39;4&#39;, &#39;3&#39;, &#39;2&#39;];

            $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 = &#39;33071919610920021X&#39;;
if (IdentityCard::isValid($num)) {
    echo &#39;身份证格式正确&#39;;
} else {
    echo &#39;身份证格式不正确&#39;;
}

다음은 신분증 인코딩 각 부분의 의미입니다.

//=============新的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位号码的第一个区别;
//13-15位为顺序号,其中15位男为单数,女为双数;
//与18位身份证号的第二个区别:没有最后一位的验证码。
//举例:
//130503 670401 001的含义; 13为河北,05为邢台,03为桥西区,出生日期为1967年4月1日,顺序号为001。

위 내용은 PHP 확인 ID 카드 형식의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제