Here's two functions that convert hex to decimal and decimal to hex. This only works with IPv6 hex and IPv6 integer representations (so, use ip2long() and long2ip() for IPv4 numbers). Theoretically, one could convert an IPv4 dotted notation number to hex values and use these, but that would probably be overkill.
This will:
- Convert all complete IPv6 numbers to a stringified long int (up to 39 characters, left padded for sorting if the flag is set to true.
- Convert a stringified "long" back to a hexidecimal IPv6 representation, left padding as necessary to the full 32 bit hex string. Colons are optionally placed, right to left, if the appropriate flag is set to true.
These can be modified to handle virtually any length hex value or virtually any length integer, and placement of colons and padding can be adjusted accordingly.
HEX to DECIMAL
function bchexdec($hex,$padl)
// Input: A hexadecimal number as a String.
// Output: The equivalent decimal number as a String.
// - if padl==true then pad left to fill 39 characters for string sort
{
if (strlen($hex) != 39)
{
$hex = inet6_expand($hex);
if ($hex == false) return false;
}
$hex=str_replace(":","",$hex);
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++)
{
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
if ($padl==true)
{
$dec=str_pad($dec,39,"0",STR_PAD_LEFT);
}
return $dec;
}
DECIMAL to HEX
function bcdechex($dec,$colon)
// Input: A decimal as a String.
// Output: The equivalent hex value.
// - if $colon==true then add colons.
{
$hex = '';
// RFC 5952, A Recommendation for IPv6 Address Text Representation, Section 4.3 Lowercase specifies letters should be lowercase. Though that generally doesn't matter, use lowercase
// to conform with the RFC for those rare systems that do so.
do
{
$last = bcmod($dec, 16);
$hex = dechex($last).$hex;
$dec = bcdiv(bcsub($dec, $last), 16);
} while($dec>0);
$hex=str_pad($hex,32,"0",STR_PAD_LEFT);
// Add colons if $colon==true
if ($colon==true)
{
$hex=strrev($hex);
$chunks=str_split($hex,4);
$hex=implode(":", $chunks);
$hex=strrev($hex);
}
return $hex;
}
This is based off of ideas and examples found in a variety of places, as well as my own needs for easily sortable and easily storable IPv6 addresses.