IP 地址验证小于或等于另一个 IP 地址

问题描述

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

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

问题

我如何断言 fromIP<=toIP

我的尝试

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

解决方法

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

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

IPv4 地址的 4 个原始字节可以用 IPAddress.GetAddressBytes() 读取。从那里,我们可以使用 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()));
,

尝试以下操作:

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;
        }

    }


}

使用 Icomparer

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;
        }

    }


}