0

IPサブネットは、ネットワークとプレフィックス長またはマスクの2つの部分で定義されます。
たとえば192.168.0.0/16(または、192.168.0.0/255.255.0.0)。

のようなIPアドレス192.168.1.1は、このサブネットと一致すると言われています。

(192.168.1.1 & 255.255.0.0) == 192.168.0.0


このように記述され たサブネットの逆と呼ばれるものに興味があります。

特定のSubnetA(たとえば、NetworkA / MaskA)の場合、SubnetA
の逆は、 k個のサブネット のリストです。

IPアドレスAがSubnetAと一致する場合、
Aはこれらのk個のサブネットのいずれとも一致せず、SubnetAと一致しない
すべてのIPアドレスBは、これらのk個のサブネットの1つと 正確に一致します。

コードは必要ありません、私は正しくて最適な方法に興味があります。


私は以下の参考のために最適化された答えを記しているので、これを問題として試みている人々の気を散らすことはありません。彼も最初にそれを正しく理解したので、ラファウの答えを受け入れ続けてきました。

4

4 に答える 4

2

のマスクされていないビットごとに 1 つのbサブネット。このようにして、 にない各アドレスは、上記のネットワークの 1 つだけに一致します。つまり、一致しない最初のビットを担当するネットワークです。AAbiAiA

于 2009-07-03T10:48:31.907 に答える
0

うーん。基本的には、同じマスクを持つA以外のサブネットだと思います...

于 2009-07-03T09:30:04.730 に答える
0

で始まるすべてのサブネットのツリーを想像すると0.0.0.0/32、サブネットにつながらないすべてのブランチが必要になります。1 ステップ (ビット) 上がり、このビットを null にして、このノードの兄弟 (適切な場所に異なるビットを持つ) をセットに追加します。(Rafał の言うことと同じですが、表現が異なるだけです。) 次のように実行できます (動作する C# コード):

using System;
using System.Text;

namespace so_subnet_complement
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter subnet in the 192.168.0.0/16 format.");
            string[] line = Console.ReadLine().Split('/');
            string[] segments = line[0].Split('.');
            uint ip = 0;
            uint multiplier = 1;
            for (int i = 3; i >= 0; i--)
            {
                ip += byte.Parse(segments[i]) * multiplier;
                multiplier *= 0x100;
            }
            int mask = int.Parse(line[1]);

            Console.WriteLine("Complement subnets:");
            writeComplementSubnets(ip, mask);
        }

        static void writeComplementSubnets(uint ip, int mask)
        {
            for (;mask < 32; mask++)
            {
                uint newIp =(uint)(ip & (0xFFFFFFFF << mask) ^ (1 << mask));
                Console.WriteLine("{0}/{1}", ipToString(newIp), mask);
            }
        }

        static string ipToString(uint ip)
        {
            StringBuilder result = new StringBuilder(15);
            uint mask = 0xFF000000;
            int shift = 24;
            for (int i = 0; i < 4; i++)
            {
                result.Append((ip & mask) >> shift);
                mask >>= 8;
                shift -= 8;
                if (i < 3)
                    result.Append('.');
            }
            return result.ToString();
        }
    }
}

最も重要なのはwriteComplementSubnets方法です。192.168.0.0IPアドレスは(私にとって)自然な表現で表されるため、0xC0A80000.

編集:ここでは再帰は絶対に不要であることに気付きました。関数型プログラミングは時々間違った考え方を引き起こすようです。

于 2009-07-03T11:13:43.047 に答える
0

このコード スニペットの参照用に最適化された回答が記載されています。

unsigned int network; // 32-bit network. Say (192.168.0.0 or 0xC0A80000)
unsigned int mask; // 32-bit mask (0xFFFF0000 for the example case)

i = 0; // to iterate over the network bits
do {
    bitmask = (unsigned int)(0x80000000 >> i)
    invmask = (unsigned int)(0xFFFFFFFF << (31-i));

    invnet = (invmask & network) ^ bitmask;
    printSubnet(invnet, invmask); // this stores/prints the subnet

} while (mask && i<32); // only while we have valid mask

ラファウも最初に正解したので、ラファウの答えを受け入れました。


の逆で192.168.0.0/16、正しさを確認します。

[1] 0.0.0.0 / 128.0.0.0         ;    00000000
[2] 128.0.0.0 / 192.0.0.0       ;    80000000
[3] 224.0.0.0 / 224.0.0.0       ;    e0000000
[4] 208.0.0.0 / 240.0.0.0       ;    d0000000
[5] 200.0.0.0 / 248.0.0.0       ;    c8000000
[6] 196.0.0.0 / 252.0.0.0       ;    c4000000
[7] 194.0.0.0 / 254.0.0.0       ;    c2000000
[8] 193.0.0.0 / 255.0.0.0       ;    c1000000
[9] 192.0.0.0 / 255.128.0.0     ;    c0000000
[10] 192.192.0.0 / 255.192.0.0  ;    c0c00000
[11] 192.128.0.0 / 255.224.0.0  ;    c0800000
[12] 192.176.0.0 / 255.240.0.0  ;    c0b00000
[13] 192.160.0.0 / 255.248.0.0  ;    c0a00000
[14] 192.172.0.0 / 255.252.0.0  ;    c0ac0000
[15] 192.170.0.0 / 255.254.0.0  ;    c0aa0000
[16] 192.169.0.0 / 255.255.0.0  ;    c0a90000
于 2013-04-10T17:40:42.147 に答える