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.
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);
}
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.
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,
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.
Pourquoi n'utilisez-vous pas IPAddress.Parse ou IPAddress.TryParse
IPAddress.Parse(stringVarialbeContainingIP)
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
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]?)$")
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;
}
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));
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;
}
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.
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;
}
}