【问题标题】:Merge IPRanges into one range将 IPRange 合并到一个范围内
【发布时间】:2013-02-20 14:54:53
【问题描述】:

我有以下小班:

public class IPRange
{
    public IPAddress From { get; set; }
    public IPAddress To { get; set; }

    public IPRange(IPAddress from, IPAddress to)
    {
        From = from;
        To = to;
    }
}

如何检查两个 IPRange 是否相互重叠,如果是,将两个 iprange 合并到一个新的 IPRange 中?解决方案必须同时兼容 IPv4 和 IPv6。

有比较两个 ipaddress 对象的方法吗?我无法立即找到它们。 例如 10.12.0.2 > 10.12.0.1 应该为真

【问题讨论】:

  • 对于 ipv4 获取它们的 int32_t 表示并进行比较
  • 128位的ipv6怎么样?
  • 你想只合并重叠的范围还是相邻的范围?

标签: c# ip-address


【解决方案1】:

您可以通过比较字节来检查任何类型(但类型相同)的两个地址,例如 IPv6 地址:

IPAddress addr1 = IPAddress.Parse("2001:db8::1:2");
IPAddress addr2 = IPAddress.Parse("2001:db8::1:1");
var bytes1 = addr1.GetAddressBytes();
var bytes2 = addr2.GetAddressBytes();
Console.WriteLine(CompareBytes(bytes1, bytes2) > 0);  // Prints: "True"

还有CompareBytes 方法:

private static int CompareBytes(byte[] left, byte[] right)
{
    // TODO: Null checks.
    // TODO: Check that left and right have the same length.

    int difference = 0;
    for (int i = left.Length - 1; i >= 0; i--)
    {
        difference = left[i] - right[i];
        if (difference != 0)
            break;
    }
    return difference;
}

无论您的代码运行的系统的字节顺序如何,这都能正常工作。


您可以将任何 IPv4 地址转换为等效的 IPv6 地址,如下所示:

var ipv6 = ipv4.MapToIPv6();

如果你确定你总是有 IPv4 地址,你可以只比较它们的整数值:

IPAddress addr1 = IPAddress.Parse("10.12.0.2");
IPAddress addr2 = IPAddress.Parse("10.12.0.1");
uint value1 = BitConverter.ToUInt32(addr1.GetAddressBytes(), 0);
uint value2 = BitConverter.ToUInt32(addr2.GetAddressBytes(), 0);
Console.WriteLine(value1 > value2);   // Prints: "True"

【讨论】:

  • 可以用字节比较 IPv4 和 IPv6,但是必须保证 IPv4 字节在数组的开头用 0 填充
  • @DariuszWawer Apparently 转换为 IPv6 的 IPv4 地址必须以 0:0:0:0:0:FFFF 为前缀。
猜你喜欢
  • 2017-02-10
  • 2019-03-21
  • 2021-02-24
  • 2021-05-20
  • 1970-01-01
  • 2015-05-26
  • 2022-11-03
  • 2014-09-07
  • 2015-05-26
相关资源
最近更新 更多