将IPv4更改为IPv6字符串

Flo*_*ens 6 php string transform ipv6

Sander Steffann我之前的一个问题中提到过:

0000:0000:0000:0000:0000:0000:192.168.0.1这样的地址写为0000:0000:0000:0000:0000:0000:c0a8:0001,这是完全相同的地址,但是以十六进制表示法.

如何在PHP中发现,如果一个地址是这样写的:比如::0000:192.168.0.10000::0000:192.168.0.10000:0000:0000:0000:0000:0000:192.168.0.1等?是否足以检查基于IP的字符串是否具有"." 和':'?

如何将其更改为完整字符串0000:0000:0000:0000:0000:0000:c0a8:0001

我是正确的,将此更改为IPv4将是这样的:

<?php 
$strIP = '0000:0000:0000:0000:0000:0000:192.168.0.1';

$strResult = substr($strIP, strrpos($strIP, ':'));

echo $strResult; //192.168.0.1 ?
?>
Run Code Online (Sandbox Code Playgroud)

...或者是正确的IP字符串表示比这个代码片段更复杂吗?

San*_*ann 2

首先:为什么你会关心地址是如何写的?inet_pton() 将为您解析所有变化并为您提供一致的结果,然后您可以将其转换为二进制、十六进制或任何您想要的结果。

::192.168.0.1所有用于转换类似内容的代码0000:0000:0000:0000:0000:0000:c0a8:0001实际上都在我的帖子中。这正是我的示例函数的作用。

如果您提供0000:0000:0000:0000:0000:0000:192.168.0.1给 inet_pton(),然后提供给 inet_ntop(),您将获得规范的 IPv6 表示法,::192.168.0.1在本例中就是如此。如果该字符串以 开头::,其余部分不包含:和 三个点,那么您可以非常确定它是 IPv4 地址;-)

要将上一个问题的答案与此问题结合起来:

function expand_ip_address($addr_str) {
  /* First convert to binary, which also does syntax checking */
  $addr_bin = @inet_pton($addr_str);
  if ($addr_bin === FALSE) {
    return FALSE;
  }

  $addr_hex = bin2hex($addr_bin);

  /* See if this is an IPv4-Compatible IPv6 address (deprecated) or an
     IPv4-Mapped IPv6 Address (used when IPv4 connections are mapped to
     an IPv6 sockets and convert it to a normal IPv4 address */
  if (strlen($addr_bin) == 16
  &&  substr($addr_hex, 0, 20) == str_repeat('0', 20)) {
    /* First 80 bits are zero: now see if bits 81-96 are either all 0 or all 1 */
    if (substr($addr_hex, 20, 4) == '0000')
    ||  substr($addr_hex, 20, 4) == 'ffff')) {
      /* Remove leading bits so only the IPv4 bits remain */
      $addr_bin = substr($addr_hex, 12);
    }
  }

  /* Then differentiate between IPv4 and IPv6 */
  if (strlen($addr_bin) == 4) {
    /* IPv4: print each byte as 3 digits and add dots between them */
    $ipv4_bytes = str_split($addr_bin);
    $ipv4_ints = array_map('ord', $ipv4_bytes);
    return vsprintf('%03d.%03d.%03d.%03d', $ipv4_ints);
  } else {
    /* IPv6: print as hex and add colons between each group of 4 hex digits */
    return implode(':', str_split($addr_hex, 4));
  }
}
Run Code Online (Sandbox Code Playgroud)