Рассчитать диапазон 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
  1. сетевой адрес: 11000000.10101000.00000000.00000000 192.168.1.0
  2. ваш широковещательный адрес: 11000000.10101000.000000000.11111111 192.168.1.255
  3. первый используемый ip-адрес: 192.168.1.1

  4. последний используемый 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]);