web-dev-qa-db-fra.com

Quelle est la meilleure façon de valider une adresse IP?

J'ai une méthode pour valider une adresse IP de paramètre. Étant nouveau dans le développement dans son ensemble, j'aimerais savoir s'il existe une meilleure façon de procéder.

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

C'est simple (je pourrais le faire) mais il semble faire l'affaire.

37
Stephen Murby

La limitation avec IPAddress.TryParse est la méthode qui vérifie si une chaîne peut être convertie en adresse IP, donc si elle est fournie avec une valeur de chaîne comme "5", il le considère comme "0.0.0.5".

Une autre approche pour valider un IPv4 pourrait être la suivante:

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

Il pourrait être testé comme:

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

La sortie sera:

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

Vous pouvez aussi utiliser IPAddress.TryParse mais il a ses limites et pourrait entraîner une analyse incorrecte.

Méthode System.Net.IPAddress.TryParse

Notez que TryParse renvoie true s'il a correctement analysé l'entrée, mais que cela ne signifie pas nécessairement que l'adresse IP résultante est valide. N'utilisez pas cette méthode pour valider les adresses IP.

Mais cela fonctionnerait avec une chaîne normale contenant au moins trois points. Quelque chose comme:

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

Avec IPAddress.TryParse vous pouvez vérifier l'existence de trois points, puis appeler TryParse comme:

public static bool ValidateIPv4(string ipString)
{
    if (ipString.Count(c => c == '.') != 3) return false;
    IPAddress address;
    return IPAddress.TryParse(ipString, out address);
}
79
Habib
using System.Net;
public static bool CheckIPValid(string strIP)
{
    IPAddress result = null;
    return
        !String.IsNullOrEmpty(strIP) &&
        IPAddress.TryParse(strIP, out result);
}

et tu as fini

Modifier 1

Ajout de quelques vérifications supplémentaires pour éviter les exceptions (qui sont coûteuses). PS, il ne gérera pas l'unicode.

Édition 2

@StephenMurby IPAddress.TryParse renverra vrai s'il a correctement analysé la chaîne. Si vous vérifiez la méthode documentation , elle lèvera une exception dans deux cas.

  1. La chaîne est nulle.
  2. La chaîne contient des caractères unicode.

C'est à vous de décider (décision de conception) si vous souhaitez lever des exceptions ou renvoyer false. En ce qui concerne l'analyse, je préfère généralement renvoyer false plutôt que des exceptions (l'hypothèse étant qu'il s'agit d'une entrée qui n'est pas garantie d'être correcte).

En décomposant la déclaration de retour, je dis,

  1. La chaîne n'est pas nulle (ni vide qui ne sera pas analysée de toute façon) [~ # ~] et [~ # ~]
  2. L'adresse IP analyse correctement.

N'oubliez pas que les expressions booléennes C # sont évaluées paresseusement , donc le CLR n'essaiera même pas d'analyser la chaîne si elle est null ou vide.

A propos des disparus si, vous pouvez faire quelque chose comme,

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

Mais tout ce que vous faites, c'est de dire si quelque chose est vrai, revenez vrai. Plus facile de renvoyer immédiatement l'expression.

13
M Afifi

Pourquoi n'utilisez-vous pas IPAddress.Parse ou IPAddress.TryParse

IPAddress.Parse(stringVarialbeContainingIP)
5
Adil

Le framework fournit la classe IPAddress qui à son tour vous fournit les méthodes Parse et TryParse.

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

La meilleure solution Regex:

^((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]?)$")
4
GGO

Sans utiliser la classe IPAddress et valider par rapport à l'octet, ce qui est bien mieux que l'approche 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;
    }
4
Yiannis Leoussis

Surpris, personne n'a proposé une solution Regex. Tout ce dont vous avez besoin est d'inclure System.Text.RegularExpressions. Pour la lisibilité à la fois dans le code réel et pour cet exemple, je segmente TOUJOURS mon modèle d'expression régulière dans un tableau de chaînes, puis le joint.

        // 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));
2
Free Radical

Vous pouvez traiter comme ça que ce soit un ipv4 ou 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;
    }
1
Yanga

Si vous voulez simplement vérifier si elle est valide, faites seulement:

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

Il sera valide même s'il est supérieur à 255 et s'il a des points, donc pas besoin de le vérifier.

0
Meroz

essayez avec ceci:

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