【问题标题】:How to determine if a string is a valid IPv4 or IPv6 address in C#?如何确定字符串是 C# 中的有效 IPv4 还是 IPv6 地址?
【发布时间】:2010-10-22 09:26:54
【问题描述】:

我知道正则表达式是 dangerous 用于验证 IP 地址,因为 IP 地址可以采用不同的形式。

我看到过关于 C 和 C++ 的类似问题,这些问题已通过 C# inet_ntop() 中不存在的函数得到解决@

我发现的 .NET 解决方案只能处理标准的“ddd.ddd.ddd.ddd”表单。有什么建议吗?

【问题讨论】:

    标签: c# .net ip-address


    【解决方案1】:

    您可以使用它来尝试解析它:

     IPAddress.TryParse
    

    然后检查AddressFamily是哪个

    对于 IPv4 返回 System.Net.Sockets.AddressFamily.InterNetwork 或对于 IPv6 返回 System.Net.Sockets.AddressFamily.InterNetworkV6。

    编辑:一些示例代码。根据需要更改:

        string input = "your IP address goes here";
    
        IPAddress address;
        if (IPAddress.TryParse(input, out address))
        {
            switch (address.AddressFamily)
            {
                case System.Net.Sockets.AddressFamily.InterNetwork:
                    // we have IPv4
                    break;
                case System.Net.Sockets.AddressFamily.InterNetworkV6:
                    // we have IPv6
                    break;
                default:
                    // umm... yeah... I'm going to need to take your red packet and...
                    break;
            }
        }
    

    【讨论】:

    • 没问题。如您所知,BCL 非常庞大。我试着每隔一段时间通读一遍,看看里面有什么。
    • 即使用户输入的是“192.169.1”,这个方法也会返回一个有效的IP4地址。
    • 是的,因为这是一个有效的 IP 地址,并且正是原始提问者通过正则表达式匹配的意思是危险的......请参阅这篇文章 stackoverflow.com/questions/12566664/… 了解 tryparse 的工作原理
    • 请注意:在localhost上运行时,HttpContext.Current.Request.UserHostAddress返回的地址被成功解析为InterNetworkV6地址(问题地址为::1我自己,在Windows上运行IIS Express 10)。可能不会有太大影响,因为它是本地主机的事情,但我想让人们知道。
    【解决方案2】:

    关于使用System.Net.IpAddress.TryParse()的警告:

    如果您传递一个包含整数(例如“3”)的字符串,TryParse 函数会将其转换为“0.0.0.3”,因此是一个有效的 InterNetworkV4 地址。因此,至少应该将重新格式化的“0.0.0.3”返回给用户应用程序,以便用户知道他们的输入是如何被解释的。

    【讨论】:

      【解决方案3】:
      string myIpString = "192.168.2.1";
      System.Net.IPAddress ipAddress = null;
      
      bool isValidIp = System.Net.IPAddress.TryParse(myIpString, out ipAddress);
      

      如果 isValidIp 为真,您可以检查 ipAddress.AddressFamily 以确定它是 IPv4 还是 IPv6。 IPv4 为 AddressFamily.InterNetwork,IPv6 为 AddressFamily.InterNetworkV6

      【讨论】:

        【解决方案4】:

        您可以查看返回Unknown , Dns, IPv4, IPv6System.Uri.CheckHostName( value )

        if( Uri.CheckHostName( value ) != UriHostNameType.Unknown)
            //then 'value' is a valid IP address or hostname
        

        【讨论】:

        • 即使用户输入的是“192.169.1”,这个方法也会返回一个有效的IP4地址。没有最后一组网络地址。
        • 很好,因为这是一个有效的 IP 地址。
        【解决方案5】:

        如果您不想解析每个整数,而只解析 IP,只需检查 . 的 IPv4 和 : 的 IPv6。

                if (input.Contains(".") || input.Contains(":"))
                {
                    IPAddress address;
                    if (IPAddress.TryParse(input, out address))
                    {
                        switch (address.AddressFamily)
                        {
                            case AddressFamily.InterNetwork:
                                return Ip4Address;
                            case AddressFamily.InterNetworkV6:
                                return Ip6Address;
                        }
                    }
                }
        

        【讨论】:

          【解决方案6】:

          您可以使用 IPAddress.GetAddressBytes().Length 属性

                  IPAddress someIP;
          
                  if (someIP.GetAddressBytes().Length == 4)
                  {
                      // IPV4
                  }
                  else (someIP.GetAddressBytes().Length == 16)
                  {
                      // IPV6
                  }
                  else
                  {
                      // Unknown
                  }
          

          我想应该可以

          【讨论】:

          • 我会改用 IPAddress.AddressFamily :-)
          【解决方案7】:

          应用于字符串或 IPAddress 的测试组合对我有用..

                  /// <summary>
              /// Test string for valid ip address format
              /// </summary>
              /// 
              /// <param name="Address">The ip address string</param>
              /// 
              /// <returns>Returns true if address is a valid format</returns>
              public static bool IsValidIP(IPAddress Ip)
              {
                  byte[] addBytes = Ip.GetAddressBytes();
          
                  switch (Ip.AddressFamily)
                  {
                      case AddressFamily.InterNetwork:
                          if (addBytes.Length == 4)
                              return true;
                          break;
                      case AddressFamily.InterNetworkV6:
                          if (addBytes.Length == 16)
                              return true;
                          break;
                      default:
                          break;
                  }
          
                  return false;
              }
          
              /// <summary>
              /// Test string for valid ip address format
              /// </summary>
              /// 
              /// <param name="Address">The ip address string</param>
              /// 
              /// <returns>Returns true if address is a valid format</returns>
              public static bool IsValidIP(string Address)
              {
                  IPAddress ip;
                  if (IPAddress.TryParse(Address, out ip))
                  {
                      switch (ip.AddressFamily)
                      {
                          case System.Net.Sockets.AddressFamily.InterNetwork:
                              if (Address.Length > 6 && Address.Contains("."))
                              {
                                  string[] s = Address.Split('.');
                                  if (s.Length == 4 && s[0].Length > 0 &&  s[1].Length > 0 &&  s[2].Length > 0 &&  s[3].Length > 0)
                                      return true;
                              }
                              break;
                          case System.Net.Sockets.AddressFamily.InterNetworkV6:
                              if (Address.Contains(":") && Address.Length > 15)
                                  return true;
                              break;
                          default:
                              break;
                      }
                  }
          
                  return false;
              }
          

          【讨论】:

            猜你喜欢
            • 2010-10-21
            • 2011-09-09
            • 2021-05-16
            • 1970-01-01
            • 2014-03-13
            • 2012-12-26
            • 2023-03-21
            • 2016-05-24
            • 2012-06-29
            相关资源
            最近更新 更多