/** * Set an arbitrary IP range. * The closest matching prefix will be calculated but the actual range * stored in the object can be arbitrary. * @param string $start Starting IP or combination "start-end" string. * @param string $end Ending IP or null. */ public function setRange($ip, $end = null) { if (strpos($ip, '-') !== false) { list($ip, $end) = array_map('trim', explode('-', $ip, 2)); } if (false === filter_var($ip, FILTER_VALIDATE_IP) || false === filter_var($end, FILTER_VALIDATE_IP)) { throw new \InvalidArgumentException("Invalid IP range \"{$ip}-{$end}\""); } // determine version (4 or 6) $this->version = false === filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 6 : 4; $this->istart = IP::inet_ptod($ip); $this->iend = IP::inet_ptod($end); // fix order if (bccomp($this->istart, $this->iend) == 1) { list($this->istart, $this->iend) = array($this->iend, $this->istart); list($ip, $end) = array($end, $ip); } $this->start = $ip; $this->end = $end; // calculate real prefix $len = $this->version == 4 ? 32 : 128; $this->prefix = $len - strlen(BC::bcdecbin(BC::bcxor($this->istart, $this->iend))); }