【问题标题】:IPV4 vs. IPV6 PHP FunctionIPV4 与 IPV6 PHP 函数
【发布时间】:2013-03-18 12:11:18
【问题描述】:

我一直在阅读有关如何确定 IP 是 IPv4 还是 IPv6 的内容,对我来说,要寻找的东西似乎很明显是否有冒号。但是,您有 IPv4 映射的 IPv6 地址和 IPv4 兼容的 IPv6 地址。在我看来,这些类型的地址既有冒号又有句点,所以与其寻找字符串开头是否没有::ffff 的解决方案,不如直接这样做:

function isIPv6($ip) {
  if(strpos($ip, ":") !== false && strpos($ip, ".") === false) {
     return true;
  }
  return false;
}

编辑:我是否遗漏了什么或者这个功能在所有情况下都能正常工作?

【问题讨论】:

  • 这是个问题吗?您似乎提供了一个检测 IPv6 的功能。
  • 能看看IP的长度吗?
  • 或者你可以让自己轻松一点,使用FILTER_FLAG_IPV4 or FILTER_FLAG_IPV6 with filter_var()
  • Shivan,我的问题是上述功能是否在所有情况下都能正常工作。类,IP 的长度似乎不是最好的解决方案,尤其是在使用速记符号时。 publib.boulder.ibm.com/infocenter/iseries/v5r3/…Jared,这似乎比上面的简单功能更昂贵 - 如果它工作正常的话。
  • 如果它工作正常?你相信你想相信的。

标签: php ipv6 ipv4


【解决方案1】:

PHP => 5.2 有一个“内置”方法可以使用filter_var 完成此操作

您的函数可能如下所示:

function isIPv6($ip) {

   if(filter_var($ip, FILTER_VALIDATE_IP)) {

       if(filter_var($ip, FILTER_FLAG_IPV6)) {
          //It is IPv6 indeed.
        } else {
          //It is IPv4
       }

   } else {
      // NOT VALID IP
   }

}

【讨论】:

  • 问题是12:29 AM 实际上会返回true。你的评价太简单了。如果你想自己实现它,那么你应该考虑使用正则表达式。
  • 好吧,这是假设该函数几乎用于任何输入。此函数旨在与有效的 IP 地址一起使用。我们已经假设输入是 IPv4 IP 或 IPv6 IP。并非每个函数都需要超级验证所有内容以确保输入有效。使用函数的程序员也需要有一些常识......
  • 叹息。 . .检查此answer on security。看看第一项。
  • 在这种情况下不会是用户输入。它将是 $_SERVER["REMOTE_ADDR"] 变量。 “输入”是指对函数的输入。我不明白为什么在这种特定情况下需要进行任何验证。
  • @JJohnson 根据服务器的设置方式,$_SERVER['REMOTE_ADDR'] 很可能不是远程用户的 IP 地址。而且您的代码最终会在其他一些上下文中被重用,在这些上下文中应该更严格地对其进行验证。最好第一次就做好。
【解决方案2】:

来自IBM

An IPv6 address can have two formats:

    Normal - Pure IPv6 format
    2001 : db8: 3333 : 4444 : 5555 : 6666 : 7777 : 8888
    Dual - IPv6 plus IPv4 formats
    2001 : db8: 3333 : 4444 : 5555 : 6666 : 1 . 2 . 3 . 4

您的功能仅验证 IPv6 的纯格式。 我也建议使用FILTER_FLAG_IPV4 or FILTER_FLAG_IPV6

function isIPv6($ip) {
  if(strpos($ip, ":") !== false && strpos($ip, ".") === false) {
     return true; //Pure format
  }
  elseif(strpos($ip, ":") !== false && strpos($ip, ".") !== false){
    return true; //dual format
  }
  else{
  return false;
  }
}

【讨论】:

  • 双 IPv6 在技术上不只是半 IPv6 格式的 IPv4 吗?
  • 你函数里的逻辑基本是return strpos($ip, ':') !== false; :)
【解决方案3】:

假设 IP 地址有效并且知道您可以拥有 IPv6 映射的 IPv4 地址,例如::ffff:127.0.0.1,只需检查: 的存在就足够了。

function isIPv6($address) 
{
    return strpos($address, ':') !== false;
}

如果它可能无效,你应该先验证它:

function isIPv6($address) 
{
    return filter_var($address, FILTER_VALIDATE_IP) && 
        strpos($address, ':') !== false;
}

顺便说一句,这也是 PHP 处理 IPv6 的方式,您可以从 the source 中看到。

【讨论】:

    猜你喜欢
    • 2016-01-17
    • 2021-11-08
    • 2013-07-03
    • 2018-06-27
    • 2016-09-19
    • 2015-03-28
    • 1970-01-01
    • 2017-12-17
    • 2012-03-25
    相关资源
    最近更新 更多