/** * Wrapper for inet_ntop() * * Converts a packed internet address to a human readable representation * inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows. * * @param string $in_addr A 32bit IPv4, or 128bit IPv6 address. * * @return mixed false on failure, * string otherwise */ function phpbb_inet_ntop($in_addr) { $in_addr = bin2hex($in_addr); switch (strlen($in_addr)) { case 8: return implode('.', array_map('hexdec', str_split($in_addr, 2))); case 32: if (substr($in_addr, 0, 24) === '00000000000000000000ffff') { return phpbb_inet_ntop(pack('H*', substr($in_addr, 24))); } $parts = str_split($in_addr, 4); $parts = preg_replace('/^0+(?!$)/', '', $parts); $ret = implode(':', $parts); $matches = array(); preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE); $matches = $matches[0]; if (empty($matches)) { return $ret; } $longest_match = ''; $longest_match_offset = 0; foreach ($matches as $match) { if (strlen($match[0]) > strlen($longest_match)) { $longest_match = $match[0]; $longest_match_offset = $match[1]; } } $ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match)); if ($longest_match_offset == strlen($ret)) { $ret .= ':'; } if ($longest_match_offset == 0) { $ret = ':' . $ret; } return $ret; default: return false; } }
/** * @dataProvider data_provider */ public function test_inet_ntop($address, $hex) { $this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex))); }