Если мы разрешим пользователям вводить несколько диапазонов ip, например 172,16,11,5-100, как я могу написать функцию для проверки того, попадает ли IP (172.16.11.50) в диапазоны?
Есть ли какая-либо существующая библиотека в .NET для использования?
Если мы разрешим пользователям вводить несколько диапазонов ip, например 172,16,11,5-100, как я могу написать функцию для проверки того, попадает ли IP (172.16.11.50) в диапазоны?
Есть ли какая-либо существующая библиотека в .NET для использования?
В инфраструктуру ничего не встроено, но создать класс IPAddressRange
не потребуется.
Вы сравниваете диапазоны, вызывая IPAddress.GetAddressBytes на нижнем адресе, верхнем адресе и сравнительном адресе. Начиная с первого байта, проверьте, находится ли адрес сравнения в диапазоне верхнего/нижнего адреса.
Этот метод работает как для адресов IPv4, так и для IPv6.
public class IPAddressRange
{
readonly AddressFamily addressFamily;
readonly byte[] lowerBytes;
readonly byte[] upperBytes;
public IPAddressRange(IPAddress lowerInclusive, IPAddress upperInclusive)
{
// Assert that lower.AddressFamily == upper.AddressFamily
this.addressFamily = lowerInclusive.AddressFamily;
this.lowerBytes = lowerInclusive.GetAddressBytes();
this.upperBytes = upperInclusive.GetAddressBytes();
}
public bool IsInRange(IPAddress address)
{
if (address.AddressFamily != addressFamily)
{
return false;
}
byte[] addressBytes = address.GetAddressBytes();
bool lowerBoundary = true, upperBoundary = true;
for (int i = 0; i < this.lowerBytes.Length &&
(lowerBoundary || upperBoundary); i++)
{
if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
(upperBoundary && addressBytes[i] > upperBytes[i]))
{
return false;
}
lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
upperBoundary &= (addressBytes[i] == upperBytes[i]);
}
return true;
}
}
Примечание. Вышеприведенный код может быть расширен, чтобы добавить общедоступные статические методы factory FromCidr(IPAddress address, int bits)
Возможно, вы захотите рассмотреть эту библиотеку с помощью @jsakamoto, которая позволяет анализировать диапазон строк IP-адресов, таких как "192.168.0.0/24" и "192.168.0.0/255.255.255.0" и "192.168.0.0-192.168.0.255"., и может conatins проверить. Эта библиотека поддерживает как IPv4, так и IPv6.
https://github.com/jsakamoto/ipaddressrange
Его также можно установить через NuGet:
http://www.nuget.org/packages/IPAddressRange/
using NetTools;
...
// rangeA.Begin is "192.168.0.0", and rangeA.End is "192.168.0.255".
var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0");
rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.
rangeA.ToCidrString(); // is 192.168.0.0/24
// rangeB.Begin is "192.168.0.10", and rangeB.End is "192.168.10.20".
var rangeB1 = IPAddressRange.Parse("192.168.0.10 - 192.168.10.20");
rangeB1.Contains(IPAddress.Parse("192.168.3.45")); // is True.
rangeB1.Contains(IPAddress.Parse("192.168.0.9")); // is False.
// Support shortcut range description.
// ("192.168.10.10-20" means range of begin:192.168.10.10 to end:192.168.10.20.)
var rangeB2 = IPAddressRange.Parse("192.168.10.10-20");
// Support CIDR expression and IPv6.
var rangeC = IPAddressRange.Parse("fe80::/10");
rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
rangeC.Contains(IPAddress.Parse("::1")); // is False.
public static bool IsInRange(string startIpAddr, string endIpAddr, string address)
{
long ipStart = BitConverter.ToInt32(IPAddress.Parse(startIpAddr).GetAddressBytes().Reverse().ToArray(), 0);
long ipEnd = BitConverter.ToInt32(IPAddress.Parse(endIpAddr).GetAddressBytes().Reverse().ToArray(), 0);
long ip = BitConverter.ToInt32(IPAddress.Parse(address).GetAddressBytes().Reverse().ToArray(), 0);
return ip >= ipStart && ip <= ipEnd; //edited
}
Console.WriteLine(IsInRange("100.0.0.1", "110.0.0.255", "102.0.0.4"));//true
Лучше всего преобразовать эти адреса в целое число, а затем выполнить сравнения.
Пример отсюда: IP для целого
Чтобы преобразовать IP-адрес в целое число, разделите его на четыре октета. Например, предоставленный ip-адрес можно разбить на:
First Octet: 217
Second Octet: 110
Third Octet: 18
Fourth Octet: 206
Чтобы вычислить десятичный адрес из точечной строки, выполните следующий расчет.
(first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)
= (first octet * 16777216) + (second octet * 65536) + (third octet * 256) + (fourth octet)
= (217 * 16777216) + (110 * 65536) + (18 * 256) + (206)
= 3647869646
Учитывая IPv6, вы можете конвертировать их в целые (128 бит и 32-битные IPv4). Посмотрите на этот вопрос: Форматирование IPv6 как int на С# и сохранение его в SQL Server
Самый простой путь - получить чтобы сделать это для вас. использование
IPAddress.Parse
для анализа адреса, тоIPAddress.GetAddressBytes
, чтобы получить "число" какbyte[]
.
Я использовал этот код в codeproject прежде, что может быть полезно для вас.
http://www.codeproject.com/KB/IP/ipnumbers.aspx
У вас есть возможность добавить в IPList
диапазон IP-номеров, определяемых номерами From IP и To IP. Метод разбивает диапазон на стандартные диапазоны IP-адресов и находит их маски. Таким образом, диапазон с "10.0.0.5" по "10.0.0.20" будет разбит на следующие диапазоны и добавлен в список: 10.0.0.5, 10.0.0.20, 10.0.0.6/31, 10.0.0.16/30 и 10.0. 0.8/29, и у вас будет возможность проверить это.
Отказ от ответственности: Класс тестируется только с простыми наборами данных, и в классе отсутствует проверка предоставленных номеров IP и масок IP. Это должно быть исправлено перед использованием в производственных средах.
репост мой ответ отсюда
Некоторое время назад мне нужно было найти местоположение данного IP. Мы получили IP из запроса. Есть бесплатные базы данных, которые дали нам это отображение. В IPv4, когда мы говорим IP как "abcd", это по существу a * (256^3) + b * (256^2) + c * (256) + d
.
http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp
поэтому, когда вы говорите, что хотите, чтобы IP-адрес начинался с "а", вы ищете IP-адреса от * 256 ^ 3 до * 256 ^ 3 + 256 * (256 ^ 2) (b = 256) + 256 * (256 ) (c = 256) + 256 (d = 256) (нижний/верхний предел может немного отличаться в зависимости от того, хотите ли вы включить/исключить ограничения).
Тем не менее, существуют определенные IP-адреса, зарезервированные для определенных целей (например, 127.0.0.1, который является localhost, 0.0.0.0 не может быть IP-адресом и т.д.).
Так что ваш запрос linq будет
from i in iList where i >= MIN && i <= MAX select i;
где iList - ваш начальный список. MIN - ваше минимальное значение для вашего диапазона. MAX - ваше максимальное значение для вашего диапазона.
Не могли бы вы определить маску подсети из вашего диапазона IP?
Если это так, возможно, вы можете использовать этот метод IsInSameSubnet.
Я хочу +1 ответ BudhiP выше, который рекомендует пакет IPAddressRange от NuGet: https://www.nuget.org/packages/IPAddressRange/
Но поскольку форматирование кода сложно в комментарии, я просто добавлю здесь практический пример кода о том, как использовать IPAddressRange.
CheckIPWhitelist считывает параметр IPWhitelist и принимает список диапазонов IP, разделенных точкой с запятой (например, "192.168.10.10-20; 192.168.125.1-150; 192.168.123.1-150"), которые IPAddressRange может анализировать. Функция перебирает диапазоны и возвращает и возвращает true, если присутствует, false, если не найден.
Эта функция VB.NET и предполагает наличие некоторых зависимостей ASP.NET (таких как пространство имен System.Web.HttpRequest).
Imports NetTools ' ref. https://www.nuget.org/packages/IPAddressRange/
Function CheckIPWhitelist() As Boolean
Dim match As Boolean = False
Dim SourceIP As String = Request.UserHostAddress()
' Examples of valid IPWhitelist ranges
' one range in longhand range format: "192.168.0.10 - 192.168.10.20"
' one range in shorthand range format: "192.168.10.10-20"
' multiple ranges separated by semicolons in shorthand range format: "192.168.10.10-20;192.168.125.1-150;192.168.123.1-150"
Dim IPWhitelist As String = ConfigurationManager.AppSettings("IPWhitelist")
Dim arrRanges As String() = IPWhitelist.Split(";")
For i As Integer = 0 To arrRanges.Length - 1
If arrRanges(i) IsNot Nothing Then
Dim range As NetTools.IPAddressRange = IPAddressRange.Parse(arrRanges(i))
If range.Contains(IPAddressRange.Parse(SourceIP)) = True Then
match = True ' IP is in the whitelist, set a boolean
Exit For
End If
End If
Next
Return match
End Function