8

たとえば、サブネット マスク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

5 に答える 5

13

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();

    }
于 2013-01-14T22:38:25.267 に答える
9

住所の範囲を決定するには、次の手順に従います。

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アドレスがあります(1つはネットワークアドレス(範囲内の最初)用で、もう1つはブロードキャストアドレス(範囲内の最後)用です) 。

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

あなたが悪い英語を読んで楽しんだことを願っています。質問があれば教えてください、ロリス

于 2013-01-14T21:52:46.037 に答える
1

はい、すべてを32ビット表現に変換します(IPv4を想定)。マスクが M で IP が IP の場合、IP 範囲は (M&IP)+1、(M&IP)+2、...、(M&IP)+(~M)-1 です。& はビット単位の AND であり、~ はビット単位の否定です。

物事を 32 ビット表現に変換するには、ip abcd の各スポットは 8 ビットの数値です。

于 2013-01-14T21:33:47.977 に答える
0

良い電話。そのために余分なライブラリを使用しないでください。とても簡単です。これは私がそれを行う方法です:

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 };
}

注:
IP を uint に変換したり、その逆に変換したりする作業をさらに行う必要があります (十分に簡単なはずです)。次に、 firstlast の間の単純な for ループを使用して、すべての IP を反復処理できます。

このようなもの(テストされていません):

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]);
于 2016-09-21T08:59:07.233 に答える