如果您想象所有子网的树从 开始0.0.0.0/32
,在每一位都有分支,那么您想要所有不通向您的子网的分支。您上一步(位),将此位清空并将该节点的兄弟(在适当的位置具有不同的位)添加到您的集合中。(这和 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
方法。IP 地址以自然(对我而言)表示形式表示,因此192.168.0.0
变为0xC0A80000
.
编辑:我意识到这里绝对不需要递归。似乎函数式编程有时会导致错误的思考。