如何确定字符串在C#中是有效的IPv4还是IPv6地址?


75

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

我已经看到了C和C ++的类似问题,这些问题是使用C#inet_ntop()中不存在的函数解决的

我发现的.NET解决方案仅处理标准的“ ddd.ddd.ddd.ddd”格式。有什么建议?

Answers:


150

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

 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;
        }
    }

4
没问题。如您所知,BCL非常庞大。我尝试不时地通读它,只是看看那里有什么。
Erich Mirabal

2
即使用户输入为“ 192.169.1”,此方法也会返回有效的IP4地址。
Alexandru Dicu 2012年

3
是的,因为这是一个有效的IP地址,并且正好是通过正则表达式进行匹配的原始要求者是危险的……请参阅此stackoverflow.com/questions/12566664/…有关tryparse的工作原理
claudekennilol

1
请注意:在localhost上运行时,从返回的地址HttpContext.Current.Request.UserHostAddress已成功解析为一个InterNetworkV6地址(有问题的地址是::1我自己的,在Windows 10上运行IIS Express)。由于这是本地主机,可能影响不大,但我希望人们知道。
Blue博士2015年

32

只是有关使用的警告System.Net.IpAddress.TryParse()

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


16
string myIpString = "192.168.2.1";
System.Net.IPAddress ipAddress = null;

bool isValidIp = System.Net.IPAddress.TryParse(myIpString, out ipAddress);

如果isValidIp为true,则可以检查ipAddress.AddressFamily以确定它是IPv4还是IPv6。它AddressFamily.InterNetwork适用于IPv4和AddressFamily.InterNetworkV6IPv6。



4

如果您不想解析每个整数,而只解析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;
                }
            }
        }

1

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

        IPAddress someIP;

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

我想应该有用


1

应用于字符串或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;
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.