/** * Compresses an IPv6 adress * * RFC 2373 allows you to compress zeros in an adress to '::'. This * function expects an valid IPv6 adress and compresses successive zeros * to '::' * * Example: FF01:0:0:0:0:0:0:101 -> FF01::101 * 0:0:0:0:0:0:0:1 -> ::1 * * Whe $ip is an already compressed adress the methode returns the value as is, * also if the adress can be compressed further. * * Example: FF01::0:1 -> FF01::0:1 * * To enforce maximum compression, you can set the second argument $force to true. * * Example: FF01::0:1 -> FF01::1 * * @param String $ip a valid IPv6-adress (hex format) * @param boolean $force if true the adress will be compresses as best as possible (since 1.2.0) * * @return tring the compressed IPv6-adress (hex format) * @access public * @see Uncompress() * @static * @author elfrink at introweb dot nl */ public static function compress($ip, $force = false) { if (false !== strpos($ip, '::')) { // its already compressed if (true == $force) { $ip = Net_IPv6::uncompress($ip); } else { return $ip; } } $prefix = Net_IPv6::getPrefixLength($ip); if (false === $prefix) { $prefix = ''; } else { $ip = Net_IPv6::removePrefixLength($ip); $prefix = '/' . $prefix; } $netmask = Net_IPv6::getNetmaskSpec($ip); $ip = Net_IPv6::removeNetmaskSpec($ip); $ipp = explode(':', $ip); for ($i = 0; $i < count($ipp); $i++) { $ipp[$i] = dechex(hexdec($ipp[$i])); } $cip = ':' . join(':', $ipp) . ':'; preg_match_all("/(:0)(:0)+/", $cip, $zeros); if (count($zeros[0]) > 0) { $match = ''; foreach ($zeros[0] as $zero) { if (strlen($zero) > strlen($match)) { $match = $zero; } } $cip = preg_replace('/' . $match . '/', ':', $cip, 1); } $cip = preg_replace('/((^:)|(:$))/', '', $cip); $cip = preg_replace('/((^:)|(:$))/', '::', $cip); if ('' != $netmask) { $cip = $cip . '/' . $netmask; } return $cip . $prefix; }
/** * Checks an IPv6 adress * * Checks if the given IP is IPv6-compatible * * @param String $ip a valid IPv6-adress * * @return Boolean true if $ip is an IPv6 adress * @access public * @static */ function checkIPv6($ip) { $ip = Net_IPv6::removePrefixLength($ip); $ip = Net_IPv6::removeNetmaskSpec($ip); $ipPart = Net_IPv6::SplitV64($ip); $count = 0; if (!empty($ipPart[0])) { $ipv6 = explode(':', $ipPart[0]); for ($i = 0; $i < count($ipv6); $i++) { if (4 < strlen($ipv6[$i])) { return false; } $dec = hexdec($ipv6[$i]); $hex = strtoupper(preg_replace("/^[0]{1,3}(.*[0-9a-fA-F])\$/", "\\1", $ipv6[$i])); if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex == strtoupper(dechex($dec))) { $count++; } } if (8 == $count) { return true; } else { if (6 == $count and !empty($ipPart[1])) { $ipv4 = explode('.', $ipPart[1]); $count = 0; for ($i = 0; $i < count($ipv4); $i++) { if ($ipv4[$i] >= 0 && (int) $ipv4[$i] <= 255 && preg_match("/^\\d{1,3}\$/", $ipv4[$i])) { $count++; } } if (4 == $count) { return true; } } else { return false; } } } else { return false; } }