【问题标题】:C# - How can I identify which IP addresses in a list belong to a specific subnet?C# - 如何识别列表中的哪些 IP 地址属于特定子网?
【发布时间】:2011-11-16 05:15:54
【问题描述】:

我有一个庞大的动态 IP 地址列表、它们的子网掩码和一组给定的子网。我需要一些代码来识别每个地址所在的子网。我保持这个相当模糊,因为我对许多不同的解决方案持开放态度。有人在 C# 中有一些代码可以做类似的事情吗?谢谢!

【问题讨论】:

标签: c# ip subnet


【解决方案1】:

这取决于您对子网的定义。如果是 IP 地址范围,您可以使用:Easiest way to check ip address against a range of values using c#

如果是掩码,您可以使用ip&(~mask) 获取下限,使用ip|(~mask) 获取范围并按上述方式进行操作。

如果子网给出了网络掩码的位数,您可以计算: mask=~(UInt32.MaxValue>>n) 并按上述方式使用。

如果您想找出给定 IP 的网络掩码,那么我不知道。也不知道 IPv6。

【讨论】:

  • 好的,你是说我应该对地址和掩码进行算术运算以找到范围,然后取该范围内的第一个地址?
  • 你的问题很模糊,很难知道你想要什么。
  • 对不起。我想给定 IP 的子网范围内的第一个地址就是我需要的。
【解决方案2】:

首先,您需要代码将地址屏蔽到其子网:

public IPAddress ApplyMask(IPAddress address, IPAddress mask) {
    byte[] addressBytes = address.GetAddressBytes();
    byte[] maskBytes = mask.GetAddressBytes();
    var appliedMaskBytes =
        addressBytes.Zip(
            maskBytes,
            (addressByte, maskByte) => (byte)(addressByte & maskByte)
        )
        .ToArray();
    return new IPAddress(appliedMaskBytes);
}

然后,假设您有一个从 IP 地址到其掩码的Dictionary<IPAddress, IPAddress>

IDictionary<IPAddress, IPAddress> maskDictionary;
var masked = ipAddresses
                 .Select(ipAddress => 
                     new { IPAddress = ipAddress,
                           Subnet = ApplyMask(
                               ipAddress,
                               maskDictionary[ipAddress]
                           )
                     }
                 )
                 .GroupBy(x => x.Subnet);

现在您有一个按子网划分的地址列表。相应地进行。

(注意:我手边没有编译器。对于编译器的小错误,请见谅。)

【讨论】:

  • 不要出任何错误,这应该让我开始。感谢您的帮助! (我会投票给你,但我没有足够的声誉。)我会在今天某个时候看看这是否有效并报告。
  • 另一个问题 - addressBytes.Zip - 我找不到那个类。你会知道它在哪个图书馆吗?
  • 我最初的实现会这样做;但我意识到{192.168.0.0, 255.255.255.0}{192.168.0.0, 255.255.0.0} 不同 - 根据这个实现它是。
  • @MyOtherCarIsEpona:它在 .NET 4.0 中;确保您使用的是System.Linq
【解决方案3】:

您不需要子网列表 - 它们可以被推断出来。你可以用一些按位数学来做到这一点:

// Key is {Subnet, Subnet Mask}.
// Value is list of IPs in that range.
public static IDictionary<Tuple<IPAddress, IPAddress>, ISet<IPAddress>> AllocateToSubnets(IEnumerable<Tuple<IPAddress, IPAddress>> ips)
{
    var dic = new Dictionary<Tuple<IPAddress, IPAddress>, ISet<IPAddress>>();
    foreach (var item in ips)
    {
        var subnet = Tuple.Create(GetSubnetAddress(item.Item1, item.Item2), item.Item2);

        ISet<IPAddress> set;
        if (!dic.TryGetValue(subnet, out set))
            dic.Add(subnet, set = new HashSet<IPAddress>());
        if (!set.Add(item.Item1))
        {
            // Throw an error if you are looking for duplicates.
        }
    }

    return dic;
}

private static IPAddress GetSubnetAddress(IPAddress address, IPAddress mask)
{
    var b1 = address.GetAddressBytes();
    var b2 = mask.GetAddressBytes();
    if (b1.Length != b2.Length)
        throw new InvalidOperationException("IPAddress and its mask do not share the same family.");
    for (var i = 0; i < b1.Length; i++)
        b1[i] &= b2[i];
    return new IPAddress(b1);
}

测试代码:

var ips = new[]
    {
        Tuple.Create(IPAddress.Parse("192.168.0.1"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("192.168.0.1"), IPAddress.Parse("255.255.0.0")),
        Tuple.Create(IPAddress.Parse("192.168.0.2"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("192.168.0.10"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("192.168.0.10"), IPAddress.Parse("255.255.0.0")),
        Tuple.Create(IPAddress.Parse("10.0.0.1"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("10.1.0.1"), IPAddress.Parse("255.255.0.0")),
        Tuple.Create(IPAddress.Parse("10.0.0.2"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("10.1.0.10"), IPAddress.Parse("255.255.255.0")),
        Tuple.Create(IPAddress.Parse("10.1.0.10"), IPAddress.Parse("255.255.0.0")),
    };

var subnets = AllocateToSubnets(ips);

【讨论】:

    猜你喜欢
    • 2011-07-26
    • 2021-12-12
    • 2019-02-09
    • 1970-01-01
    • 2012-09-21
    • 2010-11-05
    • 2017-10-30
    • 2016-12-20
    • 1970-01-01
    相关资源
    最近更新 更多