【问题标题】:IPAddress validation (less than or equal to another IPAddress)IPAddress 验证(小于或等于另一个 IPAddress)
【发布时间】:2021-07-22 16:36:30
【问题描述】:

正如标题所示,我有 2 个IPAddress 对象:

var fromIP = IPAddress.Parse("127.0.01");
var toIP = IPAddress.Parse("255.255.255.255");

问题

我如何断言fromIP<=toIP

我的尝试

我有一个笨拙的解决方案 - 由 . 拆分并遍历 IPAddress 问题的 4 个组件中的每一个,并按顺序检查每个组件。我不确定这是否无法涵盖我缺少的 IPv4/IPv6 规范的特定部分?或者是否有一种“更好”的方法来涵盖所有情况。

【问题讨论】:

  • 你做的是对的。我有时会编写一个 IComparable 类,它与您的代码已经完成的功能相同,但更简洁。我会发布我的解决方案
  • 您可以使用 TryWriteBytes 或 GetAddressBytes,然后逐字节比较?你仍然有同样的“小于是什么意思?”问题,但至少您不必拆分和解析每个令牌...
  • 已经在这里回答:stackoverflow.com/a/13631626/7149235

标签: c# .net ip-address


【解决方案1】:

IPv4 地址的点分十进制表示法只是编写 32 位 int 的一种友好方式:我们取出每个字节,写出其十进制表示,并用句点分隔它们。

因此,每个 IP 地址都可以仅表示为 32 位 int,并且可以直接进行比较。

可以使用IPAddress.GetAddressBytes() 读取 IPv4 地址的 4 个原始字节。从那里,我们可以使用BinaryPrimitives.ReadUInt32BigEndian 作为将它们转换为大端无符号 32 位整数的简单方法:

var ipAddress = IPAddress.Parse("127.0.0.1");
uint ipInt = BinaryPrimitives.ReadUInt32BigEndian(ipAddress.GetAddressBytes());

然后您可以以正常方式比较您的两个uints

如果您想将 IP 地址作为有符号整数而不是无符号整数进行比较,您可以执行类似操作:

var ipAddress = IPAddress.Parse("127.0.0.1");
int ipInt = BinaryPrimitives.ReadInt32BigEndian(ipAddress.GetAddressBytes());

BinaryPrimitives 是在 .NET Standard 2.1 中引入的。如果您遇到较旧的问题,可以使用BitConverter。但是,BitConverter 使用主机的字节序,而 IP 地址中的字节始终是大字节序,因此您必须在它们之间进行转换:

uint ipInt = unchecked((uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(ipAddress.GetAddressBytes())));

签名版就简单一点:

int ipInt = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(ipAddress.GetAddressBytes()));

【讨论】:

  • 仅供参考,您也可以在此处使用 span 来避免 byte[];没关系,除非你做了 很多,但是:sharplab.io/…
【解决方案2】:

尝试以下:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Net;

namespace ConsoleApplication
{
    public class Program
    {
        
        public static void Main(string[] args)
        {
            IPAddress ip1 = IPAddress.Parse("127.0.01");
            IPAddress ip2 = IPAddress.Parse("255.255.255.255");

            int results = (new CompareIP(ip1)).CompareTo(new CompareIP(ip2));
        }
    }
    public class CompareIP : IComparable<CompareIP>
    {
        private byte[] ipAddress { get; set; }

        public CompareIP(IPAddress ipAddress)
        {
            this.ipAddress = ipAddress.GetAddressBytes();
        }
        public int CompareTo(CompareIP  other)
        {
            int results = 0;
            for (int i = 0; i < ipAddress.Length; i++)
            {
                results = this.ipAddress[i].CompareTo(other.ipAddress[i]);
                if (results != 0) break;
            }

            return results;
        }

    }


}

使用比较器

using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Net;

namespace ConsoleApplication
{
    public class Program
    {
        
        public static void Main(string[] args)
        {
            IPAddress ip1 = IPAddress.Parse("127.0.0.1");
            IPAddress ip2 = IPAddress.Parse("255.255.255.255");

            int results = (new CompareIP()).Compare(ip1,ip2);
        }
    }
    public class CompareIP : IComparer<IPAddress>
    {
        public int Compare(IPAddress ip1, IPAddress ip2)
        {
            int results = 0;
            byte[] ip1Bytes = ip1.GetAddressBytes();
            byte[] ip2Bytes = ip2.GetAddressBytes();               
            for (int i = 0; i < ip1Bytes.Length; i++)
            {
                results = ip1Bytes[i].CompareTo(ip2Bytes[i]);
                if (results != 0) break;
            }

            return results;
        }

    }


}

【讨论】:

  • 我添加了两个解决方案。
猜你喜欢
  • 2015-07-12
  • 2023-04-01
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2022-11-11
相关资源
最近更新 更多