Рассчитать диапазон IP по маске подсети
Если у меня есть маска подсети, например 255.255.255.0
и ip-адрес 192.168.1.5
, есть ли простой способ определить все возможные ip-адреса в этой подсети?
В этом случае:
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
...
...
192.168.1.252
192.168.1.253
192.168.1.254
192.168.1.255
все, что я нашел до сих пор, - это перегруженные библиотеки .net. Нет ли собственного способа решить эту проблему с пространствами имен по умолчанию?
4 ответов
чтобы определить диапазон адресов, выполните следующие действия:
1) Возьмите маску подсети (здесь 255.255.255.0) и преобразуйте ее в двоичный код:
11111111.11111111.11111111.00000000
( 8 + 8 + 8 + 0 = 24 -> So you can write your ip adresse like this : 192.168.1.x/24 because you are in a /24 network)
2) у вас есть в сети /24 256-2=254 полезных IP-адреса для хоста (один для сетевого адреса (первый в вашем диапазоне), а другой для широковещательного адреса (последний в вашем диапазоне)).
3) чтобы получить свой диапазон, просто получите свой сетевой адрес (первый IP-адрес в соответствии с вашей маской подсети) и получите следующие 255 ip-адресов, и у вас будет свой диапазон.
сетевой адрес:
в двоичном файле последний октет должен быть равен null:
xxxxxxxx.xxxxxxxx.xxxxxxxx.00000000
ваш широковещательный адрес:
в двоичном коде последний октет должен быть равен 1:
xxxxxxxx.xxxxxxxx.xxxxxxxx.11111111
здесь ваш ip-адрес 192.168.1.5. В двоичном формате получаем:
11000000.10101000.00000000.00000101
- сетевой адрес: 11000000.10101000.00000000.00000000 192.168.1.0
- ваш широковещательный адрес: 11000000.10101000.000000000.11111111 192.168.1.255
первый используемый ip-адрес: 192.168.1.1
последний используемый ip-адрес: 192.168.1.254
Надеюсь, вам понравилось читать плохой английский. Скажите мне, если у вас есть какие-либо вопросы, Лорис!--5-->
10 минут кодирования и не полностью протестированы:
class IPSegment {
private UInt32 _ip;
private UInt32 _mask;
public IPSegment(string ip, string mask) {
_ip = ip.ParseIp();
_mask = mask.ParseIp();
}
public UInt32 NumberOfHosts {
get { return ~_mask+1; }
}
public UInt32 NetworkAddress {
get { return _ip & _mask; }
}
public UInt32 BroadcastAddress {
get { return NetworkAddress + ~_mask; }
}
public IEnumerable<UInt32> Hosts(){
for (var host = NetworkAddress+1; host < BroadcastAddress; host++) {
yield return host;
}
}
}
public static class IpHelpers {
public static string ToIpString(this UInt32 value) {
var bitmask = 0xff000000;
var parts = new string[4];
for (var i = 0; i < 4; i++) {
var masked = (value & bitmask) >> ((3-i)*8);
bitmask >>= 8;
parts[i] = masked.ToString(CultureInfo.InvariantCulture);
}
return String.Join(".", parts);
}
public static UInt32 ParseIp(this string ipAddress) {
var splitted = ipAddress.Split('.');
UInt32 ip = 0;
for (var i = 0; i < 4; i++) {
ip = (ip << 8) + UInt32.Parse(splitted[i]);
}
return ip;
}
}
использование:
static void Main(string[] args) {
IPSegment ip = new IPSegment("192.168.1.1","255.255.255.248");
Console.WriteLine(ip.NumberOfHosts);
Console.WriteLine(ip.NetworkAddress.ToIpString());
Console.WriteLine(ip.BroadcastAddress.ToIpString());
Console.WriteLine("===");
foreach (var host in ip.Hosts()) {
Console.WriteLine(host.ToIpString());
}
Console.ReadLine();
}
yup, преобразуйте все в 32-битное представление (при условии IPv4). если ваша маска-M, а ip-IP, то ваш диапазон ip - (M & IP)+1,(M&IP)+2,..., (M&IP)+(~M)-1. где & побитовое, а ~ побитовое нет.
чтобы преобразовать вещи в 32-битное представление, каждое место в ip a.b.c.d-8-разрядное число.
хороший призыв. Не используйте для этого дополнительные библиотеки. Все очень просто. Вот как я это делаю:--3-->
public static uint[] GetIpRange(string ip, IPAddress subnet)
{
uint ip2 = Utils.IPv4ToUInt(ip);
uint sub = Utils.IPv4ToUInt(subnet);
uint first = ip2 & sub;
uint last = first | (0xffffffff & ~sub);
return new uint[] { first, last };
}
Примечание:
Вам нужно будет еще немного поработать над преобразованием IPs в uint и обратно (должно быть достаточно легко). Затем вы можете повторить все IPs с помощью простого for-loop между первый и последние.
что-то вроде этого (не проверял):
byte[] bytes = subnet.GetAddressBytes();
uint sub = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
IPAddress ip1 = IPAddress.Parse(ip);
bytes = ip1.GetAddressBytes();
uint ip2 = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);