Как проверить падение входного IP-адреса в определенном диапазоне IP-адресов
Если мы позволим пользователям вводить несколько диапазонов ip, например, 172.16.11.5-100, как я могу написать функцию, чтобы проверить, попадает ли IP (172.16.11.50) в диапазоны?
есть ли какая-либо существующая библиотека в .NET для использования?
7 ответов:
там ничего не построили в рамки, но это не займет много усилий, чтобы создать
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; } }NB: приведенный выше код может быть добавить общедоступные статические методы фабрики
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 в C# и сохранение его в SQL Server
самый простой способ-получить рамки, чтобы сделать это для вас. Использовать
IPAddress.Parseдля разбора адреса, тогдаIPAddress.GetAddressBytesполучить "число" какbyte[].
я использовал этот код на codeproject, что может быть полезным для вас.
http://www.codeproject.com/KB/IP/ipnumbers.aspx
у вас есть возможность добавить к
IPListдиапазон IP-номеров, определяемых a от IP и A до 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 как "a.b.c. d" это по существу
a * (256^3) + b * (256^2) + c * (256) + d.http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp
поэтому, когда вы говорите, что хотите IP-адрес, начинающийся с "a", вы ищете IP-адреса между a * 256^ 3 и A * 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 ваш первоначальный список Мин Мин значение для диапазона максимум-это ваше максимальное значение для диапазон
не могли бы вы выяснить маска подсети из вашего диапазона IP?
Если так, то, возможно, вы могли бы использовать это IsInSameSubnet метод..
Comments