Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way of validating an IP Address?

Tags:

c#

ip

People also ask

What makes an IP address valid or invalid?

A few of the common reasons why an IP address becomes invalid are using reserved IP address ranges, using invalid IP addresses, using non-standard IP address formats, outdated IP addresses, DNS configuration issues, network card problems, and IP address conflicts.


The limitation with IPAddress.TryParse method 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".

Another approach to validate an IPv4 could be following :

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.TryParse but it has the limitations and could result in incorrect parsing.

System.Net.IPAddress.TryParse Method

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.

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.TryParse you can check for existence of three dots and then call TryParse like:

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

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

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

Edit 2

@StephenMurby IPAddress.TryParse will return true if it successfully parsed the string. If you check the documentation for the method though it will throw an exception in two cases.

  1. The string is null.
  2. The string contains unicode characters.

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).

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.

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

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.


The best Regex solution (useful for 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#

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]?)$")

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

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