Converts an IPv6 address and formats to leading 0s format

@todo Refactor the living hell out of this.  I haven't found a corner-case that doesn't work YET, but there's one out there, I know it.
@param $ipv6
@return string
@throws \Exception
975591
static public function NormalizeIPv6Address($ipv6)
    {

        if (strpos($ipv6, "::") === false && substr_count($ipv6, ":") !== 7) {
            throw new \Exception("Invalid IPv6 address");
        }

        if (strpos($ipv6, "::") !== false) {

            $padding = ":";

            $paddingRequired = 9 - substr_count($ipv6, ":");

            while (substr_count($padding, ":") < $paddingRequired) {

                $padding .= "0000:";

            }

            $ipv6 = str_replace("::", $padding, $ipv6);
        }

        $ipv6 = explode(":", $ipv6);

        foreach ($ipv6 as &$field) {

            while (strlen($field) < 4) {

                $field = "0{$field}";

            }

        }

        return implode(":", $ipv6);

    }
446243
public function getRawIpAddress($convertToInteger = FALSE)
    {
        $ip_keys = Repository\DataRepository::getData('ip_address_server');
        $this->debug->debug(__FUNCTION__, 'ip_keys: ', $ip_keys);
        foreach ($ip_keys as $key) {
            if (array_key_exists($key, $_SERVER) === TRUE) {
                foreach (explode(',', $_SERVER[$key]) as $ip) {
                    $ip = trim($ip);
                    $this->debug->debug(__FUNCTION__, 'IP: ' . $ip);
                    if ($convertToInteger === TRUE) {
                        $result = ip2long($ip);
                        $this->debug->info(__FUNCTION__, 'IP convert to Integer Result: ' . $result);

                        return $result;
                    }

                    return $ip;
                }
            }
        }
        $this->debug->warning(__FUNCTION__, 'IP Result: Missing KEY IP');

        return FALSE;
    }
687778
public function setIpAddress($ip_address)
    {

        if (!is_null($ip_address) && (!preg_match("/^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))?$/", $ip_address))) {
            throw new \InvalidArgumentException("invalid value for $ip_address when calling Server., must conform to the pattern /^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))?$/.");
        }

        $this->container['ip_address'] = $ip_address;

        return $this;
    }
72448
public function expand(): IP
    {
        $result = clone $this;

        if ($this->isIPv6) {
            $bytes = unpack('n*', inet_pton($this->address));

            $result->address = implode(
                ':',
                array_map(
                    function ($b) {
                        return sprintf('%04x', $b);
                    },
                    $bytes
                )
            );
        }

        return $result;
    }
1104670
def to_ipv6(net)
			if (!net.kind_of?(IPv6Net))
				raise ArgumentError, "Expected an IPv6Net object for 'net' but got a #{net.class}."
			end
			
			if (net.netmask.prefix_len != 64)
				return nil
			end
			
			# set u/l bit to 0
			hostId = @addr ^ 0x0200000000000000
			ipAddr = net.network.addr | hostId
			return IPv6.new(ipAddr)
		end
573600
protected function checkAndSetIpPort($ip_address)
    {

        // Test for IPv6
        if (substr_count($ip_address, ':') > 1) {
            // See if we have a port, input should be in the format [::1]:27015 or similar
            if (strstr($ip_address, ']:')) {
                // Explode to get port
                $server_addr = explode(':', $ip_address);

                // Port is the last item in the array, remove it and save
                $this->port_client = (int)array_pop($server_addr);

                // The rest is the address, recombine
                $this->ip = implode(':', $server_addr);

                unset($server_addr);
            } else {
                // Just the IPv6 address, no port defined, fail
                throw new Exception(
                    "The host address '{$ip_address}' is missing the port.  All "
                    . "servers must have a port defined!"
                );
            }

            // Now let's validate the IPv6 value sent, remove the square brackets ([]) first
            if (!filter_var(trim($this->ip, '[]'), FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV6,])) {
                throw new Exception("The IPv6 address '{$this->ip}' is invalid.");
            }
        } else {
            // We have IPv4 with a port defined
            if (strstr($ip_address, ':')) {
                list($this->ip, $this->port_client) = explode(':', $ip_address);

                // Type case the port
                $this->port_client = (int)$this->port_client;
            } else {
                // No port, fail
                throw new Exception(
                    "The host address '{$ip_address}' is missing the port. All "
                    . "servers must have a port defined!"
                );
            }

            // Validate the IPv4 value, if FALSE is not a valid IP, maybe a hostname.  Try to resolve
            if (!filter_var($this->ip, FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV4,])
                && $this->ip === gethostbyname($this->ip)
            ) {
                // When gethostbyname() fails it returns the original string
                // so if ip and the result from gethostbyname() are equal this failed.
                throw new Exception("Unable to resolve the host '{$this->ip}' to an IP address.");
            }
        }
    }
1267084
public static function isIpV6Address($value): bool
    {
        if (!static::isStringCastable($value)) {
            return false;
        }

        return filter_var((string) $value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
    }
220380
private function formatIp(string $host): string
    {
        $ip = substr($host, 1, -1);
        if (false !== filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            return $host;
        }

        if (1 === preg_match(self::REGEXP_HOST_IPFUTURE, $ip, $matches) && !in_array($matches['version'], ['4', '6'], true)) {
            return $host;
        }

        $pos = strpos($ip, '%');
        if (false === $pos) {
            throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host));
        }

        if (1 === preg_match(self::REGEXP_HOST_GEN_DELIMS, rawurldecode(substr($ip, $pos)))) {
            throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host));
        }

        $ip = substr($ip, 0, $pos);
        if (false === filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host));
        }

        //Only the address block fe80::/10 can have a Zone ID attach to
        //let's detect the link local significant 10 bits
        if (0 === strpos((string) inet_pton($ip), self::HOST_ADDRESS_BLOCK)) {
            return $host;
        }

        throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host));
    }
1127621
private String extractIPV6Brackets(String host) {
		String ret = host;
		// IPv6 here, remove square brackets
		if (host.indexOf(':') != -1) {
			int startPoint = host.indexOf('[');
			int endPoint = host.indexOf(']');
			if (endPoint == -1) endPoint = host.length();
			if (startPoint != -1) {
				ret = host.substring(startPoint + 1, endPoint);
			} else {
				ret = host.substring(0, endPoint);
			}
		}
		return ret;
	}
1268730
public function getIpV4() : ?string 
    {
        if ( ! $this->hasIpV4()) {
            $this->setIpV4($this->getDefaultIpV4());
        }
        return $this->ipV4;
    }
1134446
def _explode_shorthand_ip_string(self):
        
        if isinstance(self, IPv6Network):
            ip_str = str(self.network_address)
        elif isinstance(self, IPv6Interface):
            ip_str = str(self.ip)
        else:
            ip_str = str(self)

        ip_int = self._ip_int_from_string(ip_str)
        hex_str = '%032x' % ip_int
        parts = [hex_str[x:x+4] for x in range(0, 32, 4)]
        if isinstance(self, (_BaseNetwork, IPv6Interface)):
            return '%s/%d' % (':'.join(parts), self._prefixlen)
        return ':'.join(parts)
792383
public function getRawIpAddress($convertToInteger = FALSE)
    {
        $ip_keys = Repository\DataRepository::getData('ip_address_server');
        foreach ($ip_keys as $key) {
            if (array_key_exists($key, $_SERVER) === TRUE) {
                foreach (explode(',', $_SERVER[$key]) as $ip) {
                    $ip = trim($ip);
                    if ($this->ipValidate($ip)) {
                        if ($convertToInteger === TRUE) {
                            $result = ip2long($ip);

                            return $result;
                        }

                        return $ip;
                    }
                }
            }
        }

        return FALSE;
    }
940374
public function toString($long = false)
    {
        switch (true) {
            case $this->fromAddress instanceof \IPLib\Address\IPv4:
                $chunks = explode('.', $this->fromAddress->toString());
                $chunks = array_slice($chunks, 0, -$this->asterisksCount);
                $chunks = array_pad($chunks, 4, '*');
                $result = implode('.', $chunks);
                break;
            case $this->fromAddress instanceof \IPLib\Address\IPv6:
                if ($long) {
                    $chunks = explode(':', $this->fromAddress->toString(true));
                    $chunks = array_slice($chunks, 0, -$this->asterisksCount);
                    $chunks = array_pad($chunks, 8, '*');
                    $result = implode(':', $chunks);
                } else {
                    $chunks = explode(':', $this->toAddress->toString(false));
                    $chunkCount = count($chunks);
                    $chunks = array_slice($chunks, 0, -$this->asterisksCount);
                    $chunks = array_pad($chunks, $chunkCount, '*');
                    $result = implode(':', $chunks);
                }
                break;
            default:
                throw new \Exception('@todo'); // @codeCoverageIgnore
        }

        return $result;
    }
914488
public static function expandIncompleteIpv6(string $ip): string
    {
        $hextets = array_map(function ($hextet) {
            return str_pad($hextet, 4, '0', STR_PAD_LEFT);
        }, explode(':', $ip));

        return implode(':', $hextets);
    }
1069537
private function isValidIpv6Hostname(string $host): bool
    {
        [$ipv6, $scope] = explode('%', $host, 2) + [1 => null];
        if (null === $scope) {
            return (bool) filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
        }

        $scope = rawurldecode('%'.$scope);

        return 1 !== preg_match(self::REGEXP_NON_ASCII_PATTERN, $scope)
            && 1 !== preg_match(self::REGEXP_GEN_DELIMS, $scope)
            && filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)
            && 0 === strpos((string) inet_pton((string) $ipv6), self::ADDRESS_BLOCK);
    }
271630
public static function reverseIpv4(string $ip): string
    {
        $octets = array_reverse(explode('.', $ip));

        return implode('.', $octets).'.in-addr.arpa.';
    }
1244050
public function getIpAddress()
    {
        $pattern = new UriPattern();
        $pattern->matchHost($this->getHost(), $match);

        if (isset($match['IPv4address'])) {
            return $match['IPv4address'];
        } elseif (isset($match['IP_literal'])) {
            return preg_replace('/^\\[(v[^.]+\\.)?([^\\]]+)\\]$/', '$2', $match['IP_literal']);
        }

        return null;
    }