Каков наилучший способ проверки IP-адреса?
У меня есть метод для проверки 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;
}
Его простой (я мог бы это сделать), но, похоже, это трюк.
Ответы
Ответ 1
Ограничение с помощью метода IPAddress.TryParse
заключается в том, что он проверяет, может ли строка быть преобразована в IP-адрес, поэтому, если она снабжена строковым значением типа "5"
, оно считает это "0.0.0.5"
.
Другой подход к проверке 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));
}
Его можно было протестировать следующим образом:
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)}");
}
Выход будет:
2 ==> False
1.2.3 ==> False
1.2.3.4 ==> True
255.256.267.300 ==> False
127.0.0.1 ==> True
Вы также можете использовать IPAddress.TryParse
но он имеет ограничения и может привести к некорректному разбору.
Метод System.Net.IPAddress.TryParse
Обратите внимание, что TryParse возвращает true, если он успешно разбирает вход, но это не обязательно означает, что результирующий IP-адрес является допустимым. Не используйте этот метод для проверки IP-адресов.
Но это будет работать с нормальной строкой, содержащей не менее трех точек. Что-то вроде:
string addrString = "192.168.0.1";
IPAddress address;
if (IPAddress.TryParse(addrString, out address)) {
//Valid IP, with address containing the IP
} else {
//Invalid IP
}
С помощью 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);
}
Ответ 2
using System.Net;
public static bool CheckIPValid(string strIP)
{
IPAddress result = null;
return
!String.IsNullOrEmpty(strIP) &&
IPAddress.TryParse(strIP, out result);
}
и вы сделали
Редактировать 1
Добавлены некоторые дополнительные проверки для предотвращения исключения исключений (которые являются дорогостоящими). PS он не будет обрабатывать unicode.
Изменить 2
@StephenMurby IPAddress.TryParse
вернет true, если он успешно проанализировал строку. Если вы проверите документацию по методу, хотя в двух случаях он будет генерировать исключение.
- Строка имеет значение NULL.
- Строка содержит символы Unicode.
Вам решать (принять решение), хотите ли вы выкидывать исключения или возвращать false. Когда дело доходит до разбора, я обычно предпочитаю возвращать ложные, а не исключения (предположение, что это вход, который не гарантированно будет правильным).
Я говорю, нарушая выражение о возвращении,
- Строка не является нулевой (и пустой, которая не будет разбираться в любом случае) И
- IP-адрес правильно анализируется.
Помните, что логические выражения С# ленивы, поэтому CLR не попытается даже проанализировать строку, если она является null
или пустой.
Про недостающие, если, вы можете сделать что-то вроде,
if (IP.TryParse(strIP, out result)
{
return true;
}
Но все, что вы действительно делаете, говорит, что если что-то истинно, верните истину. Легче просто вернуть выражение сразу.
Ответ 3
Почему вы не используете IPAddress.Parse или IPAddress.TryParse
IPAddress.Parse(stringVarialbeContainingIP)
Ответ 4
Структура предоставляет класс IPAddress
который, в свою очередь, предоставляет вам методы Parse
и TryParse
.
// myAddress is a System.Net.IPAddress instance
if (System.Net.IPAddress.TryParse(strIP , out myAddress))
// IP is valid
else
// IP isn't valid
Ответ 5
Без использования класса 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;
}
Ответ 6
Лучшее решение 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]?)$
С#
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]?)$")
Ответ 7
Удивленный никто не предлагал решение 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));
Ответ 8
попробуйте с этим:
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;
}
}
Ответ 9
Если вы хотите просто проверить, действует ли только действие:
bool isValid = IPAddress.TryParse(stringIP, out IPAddress _);
Он будет действителен, даже если это выше 255 и если есть точки, поэтому нет необходимости его проверять.
Ответ 10
Вы можете обрабатывать так, что это либо 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;
}