67

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.

/// <summary>
/// Check IP Address, will accept 0.0.0.0 as a valid IP
/// </summary>
/// <param name="strIP"></param>
/// <returns></returns>
public bool 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.

Zahra Bayat
  • 903
  • 3
  • 11
  • 14
Stephen Murby
  • 1,407
  • 3
  • 17
  • 37
  • I don't want this to be to much discussion based, as that is not what SO is for. How ever i did want to post to see if I got an interesting response. – Stephen Murby Jul 10 '12 at 12:07
  • I had no idea that IPAddress.Parse() actually validated it as such. I just thought it changed a 12 digit long integer into the IP address format. Really useful if it does (even if it makes me a little stupid). – Stephen Murby Jul 10 '12 at 12:12
  • 1
    besides the "out of the box" answers provided I would change `arrOctets.Length != 4` to `arrOctets.Length < 3` because what if someone passed in `123.123.123.123.123`? that's not 4 and still not a valid v4 address. – Eonasdan Jul 10 '12 at 12:13
  • That the address is a valid one, IE between 1.0.0.0 and 254.254.254.254. Network address's included of course – Stephen Murby Jul 10 '12 at 12:13
  • @Eonasdan perfect. I hadn't seen it but would mess things up should someone enter it :) – Stephen Murby Jul 10 '12 at 12:14
  • Yup. Don't you love it when you do hard work to find out the framework already does it for you :P – Eonasdan Jul 10 '12 at 12:17
  • @Eonasdan infact, would arrOctets == 3, be the best of all. It should never be any different should it? – Stephen Murby Jul 10 '12 at 12:17
  • @Eonasdan Fortunately it hasn't happened alot yet, but im sure that in time it will. I'm sure it keeps changing :P – Stephen Murby Jul 10 '12 at 12:21
  • mmm if you change it that would I would think you would have to wrap the rest of your function inside that if. rather then just returning false at that point. if the length is 3 then do this, other wise exit. Or if it's more than three exit, other wise continue. – Eonasdan Jul 10 '12 at 12:57
  • 2
    @Eonasdan: No, `Length != 4` is the correct test, it rejects both too many and too few (fewer than four fields arguably are alternate encodings, but should be rejected unless you actually want the flexibility). The length of the Split output is NOT the number of separators found, so inequality comparison against 3 is wrong. – Ben Voigt Jul 24 '15 at 13:43
  • Just check on below link https://lncharan.blogspot.com/2020/09/validate-ip-address-in-c.html – Laxminarayan Charan Sep 01 '20 at 15:22

14 Answers14

137

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);
}
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 3
    IPAddress.TryParse used as indicated above will declare certain strings as valid, among other cases, 0.0.0.0 is validated successfully which for most uses would probably not be desirable. – Duncan Apr 12 '14 at 11:46
  • WARNING: This shows `127.0.0` as valid IP. To be precise, I splitted the the string first by `.` and confirmed that it has 4 splits. – Mangesh Aug 12 '16 at 06:48
  • "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." https://msdn.microsoft.com/en-us/library/system.net.ipaddress.tryparse(v=vs.110).aspx If you pass a string containing an integer (e.g. "5") the TryParse function will convert it to "0.0.0.5" and, therefore, a valid... this is just wrong! – Roy Doron Aug 29 '16 at 07:21
  • 1
    This works fairly good, however, besides the case presented by @mangesh, the following are also true: `127.000000000.0.1 => True` `127.-0.0.1 => True` – marsop Mar 29 '17 at 12:08
  • Yeah, [`byte.TryParse`](https://msdn.microsoft.com/en-us/library/f78h0es7(v=vs.110).aspx) allows a lot of weird little variations that other programs might not. I suggest adding something like `&& tempForParsing.ToString() == r` to the `All()`. – Deantwo Jun 07 '18 at 08:22
  • 11
    [`IPAddress.TryParse`](https://msdn.microsoft.com/en-us/library/system.net.ipaddress.tryparse(v=vs.110).aspx) might be easier to use if you add `&& address.ToString() == ipString` to it. Then you shouldn't have to count the dots. And it might work for both IPv4 and IPv6. – Deantwo Jun 07 '18 at 08:46
  • I tested this by putting in "12.64", which was successfully parsed to "12.0.0.64". This is not a good method for validating IP Addresses. – computercarguy Jun 02 '20 at 21:34
20

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]?)$")
GGO
  • 2,678
  • 4
  • 20
  • 42
15
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.

M Afifi
  • 4,645
  • 2
  • 28
  • 48
  • @M Afifi I have to say, I don't really understand what is going on up there. Could you do a line by line(just the return)? To me it is missing an if is it not? – Stephen Murby Jul 10 '12 at 12:19
  • 1
    @StephenMurby modified my asnwer to hopefully address your question. – M Afifi Jul 10 '12 at 12:58
  • It does exactly what I assumed it did, however I was unaware that you could have the return at the bottom structured like that. I would have expected to have needed if(a && b) return true. Thankyou for the clarification though +5(if i could) – Stephen Murby Jul 10 '12 at 20:01
  • Could just add `&& result.ToString() == strIP`. It should fix a lot of the possible issues with [`IPAddress.TryParse`](https://msdn.microsoft.com/en-us/library/system.net.ipaddress.tryparse(v=vs.110).aspx). – Deantwo Jun 07 '18 at 08:28
  • 1
    I tested `IPAddress.TryParse` by putting in "12.64", which was successfully parsed to "12.0.0.64". This is not a good method for validating IP Addresses. – computercarguy Jun 02 '20 at 21:36
7

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;
    }
  • I can't access IPAddress class so this was helpful. However, I think it should fail on `byte.TryParse(strOctet, out obyte) == false` and I also added a first pass `.Split(':')` at the top to parse out any port number. Thanks for the lead! – imnk Jun 05 '15 at 16:08
  • You are right, it is the exact opposite. I will update it. Just wrote it on the fly, haven't tested it. – Yiannis Leoussis Jul 24 '15 at 13:32
  • Very nice and performance-effective solution. `IPAddress.TryParse` is very slow… – bpiec Jan 26 '16 at 17:01
2

The framework provides the IPAddress class which in turn provides you the Parse and TryParse methods.

// myAddress is a System.Net.IPAddress instance
if (System.Net.IPAddress.TryParse(strIP , out myAddress)) 
    // IP is valid
else
    // IP isn't valid
Alex
  • 23,004
  • 4
  • 39
  • 73
2

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.

        // 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));
Free Radical
  • 374
  • 1
  • 4
  • 14
2

You can process like that it it is either an ipv4 or 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;
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Yanga
  • 2,885
  • 1
  • 29
  • 32
0

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;
        }
    }
Musculaa
  • 934
  • 10
  • 19
0

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

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.

Meroz
  • 859
  • 2
  • 8
  • 28
0

For validating IP Address, use below package

Packages:-

using System.Net;  //To use IPAddress, inbuilt functionality
using System.Net.Sockets; //To access AddressFamily,
using System.Text.RegularExpression; //For Regex.IsMatch()

Method:-

public bool ValidIPAddress(string IP)
{
    //Validate IP Address , neither IPV4, or V6

    if (IPAddress.TryParse(IP, out var address) == false)
       return false;
    //check for IPV6

    if (address.AddressFamily == AddressFamily.InterNetworkV6)

    {

        if (IP.IndexOf("::") > -1)

            return true;

        return false;

    }

    //check for IPV4

    else

    {

    //Ipv4 address shouldn't start with 0 eg..it is invalid 0XX.0XX.0XX.0XX
        if (Regex.IsMatch(IP, @"(^0\d|\.0\d)"))

            return false;

        else if (IP.Count(c => c == '.') != 3)

            return false;

        else

            return true;

    }

}

check on below link if needed:-

https://lncharan.blogspot.com/2020/09/validate-ip-address-in-c.html

4b0
  • 21,981
  • 30
  • 95
  • 142
  • A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – Adrian Mole Sep 01 '20 at 15:24
0

There is an easy way to do this, but it requires internet connection to check the IP or host name:

using System;
using System.Net;

var dnsAddress = ///

try
{
    // IP like 8.8.8.8
    if (IPAddress.TryParse(dnsAddress, out var ipAddress)
        && Dns.GetHostAddresses(ipAddress.ToString()).Length >= 1)
    {
        return true;
    }

    // Hostname like smtp.gmail.com
    if (Dns.GetHostEntry(dnsAddress).AddressList.Length >= 1)
    {
        return true;
    }

    return false;
}
catch (Exception exception) when (
            exception is ArgumentNullException
            || exception is ArgumentOutOfRangeException
            || exception is System.Net.Sockets.SocketException
            || exception is ArgumentException
)
{
    // Write log message, if necessary

    return false;
}
Rony Mesquita
  • 541
  • 4
  • 9
0
//To accept values where the ip does not contain zero in the first position of the IPv4 in C# code
  /// <summary>
   /// Check IP Address, will accept [255-1].0.0.0 as a valid IP
   /// </summary>
   /// <param name="strIP"></param>
   /// <returns></returns>
   public bool CheckIPv4Valid(string strIPv4)
        {
            //  Split string by ".", check that array length is 3
            char chrFullStop = '.';
            string[] arrOctets = strIPv4.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 tempNumber; // Parse returns Int32
            #region New code
            Int32 tempNumberCero;
            tempNumberCero = int.Parse(arrOctets[0]);
            if (tempNumberCero <= 0)
            {
                return false;
            }
            #endregion
            foreach (string strOctet in arrOctets)
            {
                if (strOctet.Length > 3)
                {
                    return false;
                }
                tempNumber = int.Parse(strOctet);
                if ((tempNumber > MAXVALUE))
                {
                    return false;
                }
            }
            return true;
        }
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 07 '22 at 05:04
0

i would like to share my solution with you. It based on Regex and is inspired from Oreilly Regular Expression Cookbook.

    public class ValidAndCleanedIP 
    { 
        public bool IsValid { get; set; }
        public string IP { get; set; }
    }
    public ValidAndCleanedIP ValidAndCleanIP(string ip)
    {
        // ^(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) (?!0) check if the numeric part starts not with zero, optional you can use this pattern (25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1][0-9]|[1-9])
        // there is no check for leading zero becaus there is it possible to order the IP Addresses
        string pattern = "" +
            "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

        Regex regex = new Regex(pattern);
        bool test = regex.IsMatch(ip);

        ValidAndCleanedIP validAndCleanedIP = new ValidAndCleanedIP();

        validAndCleanedIP.IsValid = test;
        if (test)
        {
            //version removes leading zeros after the dots
            validAndCleanedIP.IP = new Version(ip).ToString();
        }
        else
        {
            validAndCleanedIP.IP = string.Empty;
        }

        return validAndCleanedIP;
    }

or the simpler Solution

    public bool Is_Valid_IP(string ip)
    {
        // (?!0) check if the numeric part starts not with zero
        string pattern = "" +
            "^(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
            "(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

        Regex regex = new Regex(pattern);

        return regex.IsMatch(ip);            
    }

nice day for all

0

Wow! For a simple one-line code, answers are getting colossal content.

Look at this!

using System.Text.RegularExpressions;

namespace Helper;

public class IpHelper
{
    public static bool IsIpValid(string ip) =>
        new Regex("^(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?!0)(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
            .IsMatch(ip);
}

Usage:

IpHelper.IsIpValid("192.168.1.1"):
Erçin Dedeoğlu
  • 4,950
  • 4
  • 49
  • 69