<?php
/**
 * Created by PhpStorm.
 * User: sunmoon
 * Date: 2018/8/25
 * Time: 上午10:49
 */

namespace common\libs;

class LoginIpChecker {
    private $_ip;
    private $_bindIp;
    /**
     * LoginIpChecker constructor.
     * @param $ip
     * @param $this->_bindIp
     */
    public function __construct($ip, $bindIp) {
        $this->_ip = $ip;
        $this->_bindIp = $bindIp;
    }

    /**
     * 掩码模式验证
     * @return bool
     */
    private function _mask(){
        $ip = (double) (sprintf("%u", ip2long($this->_ip)));
        $s = explode('/', $this->_bindIp);
        $start = (double) (sprintf("%u", ip2long($s[0])));
        $len = pow(2, 32 - $s[1]);
        $end = $start + $len - 1;
        if ($ip >= $start && $ip <= $end) {
            return true;
        }
        return false;
    }

    /**
     * 验证ip段
     * @return bool
     */
    private function _range(){
        if(strpos($this->_bindIp, '-') !== false){
            list($startIp, $endIp) = explode('-', $this->_bindIp);
            if(strpos($endIp, '.') === false){  //127.0.0.2-254
                $start = explode('.', $startIp);
                $endIp = $start[0] . '.' . $start[1] . '.' . $start[2] . '.' . $endIp;
            }

            $startIp = $this->_getIplong($startIp);
            $endIp = $this->_getIplong($endIp);
            $ip = $this->_getIplong($this->_ip);

            if($ip >= $startIp && $ip <=$endIp){
                return true;
            }
            return false;
        }else{ //单个ip 127.0.0.1
            if($this->_bindIp == $this->_ip){
                return true;
            }
            return false;
        }
    }
    /**
     * bindec(decbin(ip2long('这里填ip地址')));
     * ip2long();的意思是将IP地址转换成整型 ，
     * 之所以要decbin和bindec一下是为了防止IP数值过大int型存储不了出现负数。
     * @param $ip
     * @return float|int
     */
    private function _getIplong($ip){
        return bindec(decbin(ip2long($ip)));
    }

    /**
     * 验证
     * @return bool
     */
    public function validate(){
        if(strpos($this->_bindIp, '/') !== false){  //掩码模式  127.0.0.1/24
            $result = $this->_mask();
        }else{ // ip段10.0.0.1-254 OR 10.0.0.1-10.0.0.254
            $result = $this->_range();
        }
        return $result;
    }
}