我有一个大型动态IP地址列表,它们的子网掩码和一组给定的子网。我需要一些代码才能识别每个地址所在的子网。我保持这个相当模糊,因为我对许多不同的解决方案持开放态度。有没有人在C#中有一些可以做类似的代码?谢谢!
答案 0 :(得分: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);
现在您有一个子网列表。继续相应。
(注意:我没有编译器方便。很抱歉有轻微的编译器错误。)
答案 1 :(得分:1)
您不需要子网列表 - 可以推断它们。你可以通过一些按位数学来做到这一点:
// 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);
答案 2 :(得分:0)
这取决于您的子网定义有哪些。如果是IP地址范围,您可以使用:Easiest way to check ip address against a range of values using c#
如果是面具,您可以使用ip&(~mask)
获取较低的ip|(~mask)
来获取范围并按上述步骤继续操作。
如果为子网提供了网络掩码所具有的位数,您可以计算:
mask=~(UInt32.MaxValue>>n)
并按上述步骤使用。
如果你想找出给定IP的网络掩码,那么我就不知道了。也不了解IPv6。