C# 验证 IP 地址的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11412956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:46:55  来源:igfitidea点击:

What is the best way of validating an IP Address?

c#ip

提问by Stephen Murby

I have a method to validate a parameter IP Address. Being new to development as a whole I would like to know if there is a better way of doing this.

我有一种方法来验证参数 IP 地址。作为一个整体的开发新手,我想知道是否有更好的方法来做到这一点。

/// <summary>
/// Check IP Address, will accept 0.0.0.0 as a valid IP
/// </summary>
/// <param name="strIP"></param>
/// <returns></returns>
public Boolean CheckIPValid(String strIP)
{
    //  Split string by ".", check that array length is 3
    char chrFullStop = '.';
    string[] arrOctets = strIP.Split(chrFullStop);
    if (arrOctets.Length != 4)
    {
        return false;
    }
    //  Check each substring checking that the int value is less than 255 and that is char[] length is !> 2
    Int16 MAXVALUE = 255;
    Int32 temp; // Parse returns Int32
    foreach (String strOctet in arrOctets)
    {
        if (strOctet.Length > 3)
        {
            return false;
        }

        temp = int.Parse(strOctet);
        if (temp > MAXVALUE)
        {
            return false;
        }
    }
    return true;
}

Its simple (I could do it) but it seems to do the trick.

它很简单(我可以做到)但它似乎可以解决问题。

采纳答案by Habib

The limitationwith IPAddress.TryParsemethod is that it verifies if a string could be converted to IP address, thus if it is supplied with a string value like "5", it consider it as "0.0.0.5".

所述限制IPAddress.TryParse方法是,它验证是否字符串可能被转换成IP地址,因此,如果它与像一个字符串值供给"5",它认为它是"0.0.0.5"

Another approach to validate an IPv4 could be following :

另一种验证 IPv4 的方法可能如下:

public bool ValidateIPv4(string ipString)
{
    if (String.IsNullOrWhiteSpace(ipString))
    {
        return false;
    }

    string[] splitValues = ipString.Split('.');
    if (splitValues.Length != 4)
    {
        return false;
    }

    byte tempForParsing;

    return splitValues.All(r => byte.TryParse(r, out tempForParsing));
}

It could be tested like:

可以这样测试:

List<string> ipAddresses = new List<string>
{
    "2",
    "1.2.3",
    "1.2.3.4",
    "255.256.267.300",
    "127.0.0.1",
};
foreach (var ip in ipAddresses)
{
    Console.WriteLine($"{ip} ==> {ValidateIPv4(ip)}");
}

The output will be:

输出将是:

2 ==> False
1.2.3 ==> False
1.2.3.4 ==> True
255.256.267.300 ==> False
127.0.0.1 ==> True

You can also use IPAddress.TryParsebut it has the limitations and could result in incorrect parsing.

您也可以使用,IPAddress.TryParse但它有局限性,可能会导致解析错误。

System.Net.IPAddress.TryParse Method

System.Net.IPAddress.TryParse 方法

Note that TryParse returns true if it parsed the input successfully, but that this does not necessarily mean that the resulting IP address is a valid one. Do not use this method to validate IP addresses.

请注意,如果 TryParse 成功解析输入,则它会返回 true,但这并不一定意味着生成的 IP 地址是有效的。不要使用此方法来验证 IP 地址。

But this would work with normal string containing at least three dots. Something like:

但这适用于包含至少三个点的普通字符串。就像是:

string addrString = "192.168.0.1";
IPAddress address;
if (IPAddress.TryParse(addrString, out address)) {
       //Valid IP, with address containing the IP
} else {
       //Invalid IP
}

With IPAddress.TryParseyou can check for existence of three dots and then call TryParselike:

随着IPAddress.TryParse您可以检查三个点的存在,然后调用TryParse,如:

public static bool ValidateIPv4(string ipString)
{
    if (ipString.Count(c => c == '.') != 3) return false;
    IPAddress address;
    return IPAddress.TryParse(ipString, out address);
}

回答by Adil

Why dont you use IPAddress.Parseor IPAddress.TryParse

为什么不使用IPAddress.ParseIPAddress.TryParse

IPAddress.Parse(stringVarialbeContainingIP)

回答by M Afifi

using System.Net;
public static bool CheckIPValid(string strIP)
{
    IPAddress result = null;
    return
        !String.IsNullOrEmpty(strIP) &&
        IPAddress.TryParse(strIP, out result);
}

and you're done

你就完成了

Edit 1

编辑 1

Added some additional checks to prevent exceptions being thrown (which are costly). PS it won't handle unicode.

添加了一些额外的检查以防止抛出异常(代价高昂)。PS它不会处理unicode。

Edit 2

编辑 2

@StephenMurby IPAddress.TryParsewill return trueif it successfully parsed the string. If you check the documentationfor the method though it will throw an exception in two cases.

如果成功解析字符串,@StephenMurbyIPAddress.TryParse将返回true。如果您检查该方法的文档,尽管它会在两种情况下抛出异常。

  1. The string is null.
  2. The string contains unicode characters.
  1. 字符串为空。
  2. 该字符串包含 unicode 字符。

Its up to you to decide (design decision) whether you want to throw exceptions or return false. When it comes to parsing I generally prefer to return false rather than exceptions (the assumption being this is input that's not guaranteed to be correct).

由您决定(设计决定)是要抛出异常还是返回 false。在解析时,我通常更喜欢返回 false 而不是异常(假设这是不能保证正确的输入)。

Breaking the return statement down, I am saying,

打破退货声明,我是说,

  1. The string is not null (nor empty which won't parse anyway) AND
  2. The IP address parses correctly.
  1. 字符串不为空(也不为空,无论如何都不会解析)
  2. IP 地址解析正确。

Remember C# boolean expressions are lazy evaluated, so the CLR won't attempt to even parse the string if it is nullor empty.

请记住,C# 布尔表达式是惰性求值的,因此 CLR 甚至不会尝试解析字符串,如果它是null或为空。

About the missing if, you can do something like,

关于丢失的如果,你可以做类似的事情,

if (IP.TryParse(strIP, out result)
{
    return true;
}

But all you really doing is saying if something is true, return true. Easier to just return the expression straight away.

但是你真正要做的就是说如果某事是真的,就返回真。更容易直接返回表达式。

回答by Alex

The framework provides the IPAddressclass which in turn provides you the Parseand TryParsemethods.

该框架提供了IPAddress类,而类又为您提供了ParseTryParse方法。

// myAddress is a System.Net.IPAddress instance
if (System.Net.IPAddress.TryParse(strIP , out myAddress)) 
    // IP is valid
else
    // IP isn't valid

回答by Yiannis Leoussis

Without using IPAddress class and validating against byte, which is far better than the Int<256 approach.

不使用 IPAddress 类并针对字节进行验证,这比 Int<256 方法要好得多。

    public Boolean CheckIPValid(String strIP)
    {
        //  Split string by ".", check that array length is 4
        string[] arrOctets = strIP.Split('.');
        if (arrOctets.Length != 4)
            return false;

        //Check each substring checking that parses to byte
        byte obyte = 0;
        foreach (string strOctet in arrOctets)
            if (!byte.TryParse(strOctet, out obyte)) 
                return false;

        return true;
    }

回答by Musculaa

try with this:

试试这个:

private bool IsValidIP(String ip)
    {
        try
        {
            if (ip == null || ip.Length == 0)
            {
                return false;
            }

            String[] parts = ip.Split(new[] { "." }, StringSplitOptions.None);
            if (parts.Length != 4)
            {
                return false;
            }

            foreach (String s in parts)
            {
                int i = Int32.Parse(s);
                if ((i < 0) || (i > 255))
                {
                    return false;
                }
            }
            if (ip.EndsWith("."))
            {
                return false;
            }

            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }

回答by Free Radical

Surprised no one offered a Regex solution. All you need is to include System.Text.RegularExpressions. For readability both in actual code and for this example, I ALWAYS chunk my regex pattern into a string array and then join it.

令人惊讶的是,没有人提供 Regex 解决方案。您只需要包含 System.Text.RegularExpressions。为了实际代码和本示例的可读性,我总是将我的正则表达式模式分块到一个字符串数组中,然后加入它。

        // Any IP Address
        var Value = "192.168.0.55"; 
        var Pattern = new string[]
        {
            "^",                                            // Start of string
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",    // Between 000 and 255 and "."
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])",      // Same as before, no period
            "$",                                            // End of string
        };

        // Evaluates to true 
        var Match = Regex.IsMatch(Value, string.Join(string.Empty, Pattern));

回答by GGO

The best Regex solution (useful for MVC DataAnnotations) :

最好的正则表达式解决方案(对 MVC DataAnnotations 有用):

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

C#

C#

Regex.IsMatch(value, "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")

回答by Meroz

If you want to just check if is valid do only:

如果您只想检查是否有效,请仅执行以下操作:

bool isValid = IPAddress.TryParse(stringIP, out IPAddress _);

bool isValid = IPAddress.TryParse(stringIP, out IPAddress _);

It will valid even if this is above 255 and if have dots, so no need to check it.

即使它高于 255 并且有点,它也将有效,因此无需检查它。

回答by Yanga

You can process like that it it is either an ipv4 or ipv6:

您可以这样处理它是 ipv4 或 ipv6:

    public static string CheckIPValid(string strIP)
    {
        //IPAddress result = null;
        //return !String.IsNullOrEmpty(strIP) && IPAddress.TryParse(strIP, out result);
        IPAddress address;
        if (IPAddress.TryParse(strIP, out address))
        {
            switch (address.AddressFamily)
            {
                case System.Net.Sockets.AddressFamily.InterNetwork:
                    // we have IPv4
                    return "ipv4";
                //break;
                case System.Net.Sockets.AddressFamily.InterNetworkV6:
                    // we have IPv6
                    return "ipv6";
                //break;
                default:
                    // umm... yeah... I'm going to need to take your red packet and...
                    return null;
                    //break;
            }
        }
        return null;
    }