如何使用 c# 对 IP 地址列表进行排序

Posted

技术标签:

【中文标题】如何使用 c# 对 IP 地址列表进行排序【英文标题】:How to sort list of Ip Addresses using c# 【发布时间】:2011-09-09 00:50:07 【问题描述】:

我有一个如下的 IP 地址列表

192.168.1.5
69.52.220.44
10.152.16.23
192.168.3.10
192.168.1.4
192.168.2.1

我正在寻找一种方法来排序此列表以匹配以下顺序

10.152.16.23
69.52.220.44
192.168.1.4
192.168.1.5
192.168.2.1

【问题讨论】:

【参考方案1】:

简单的解决方案不需要任何黑客。只需拆分()地址段,用零填充段,然后将它们重新连接在一起。将这一行静态方法放入静态类中,如下所示:

public static class StringHelper

    public static string IpAddressLabel(string ipAddress)
        => string.Join(".", ipAddress.Split('.').Select(part => part.PadLeft(3, '0')));

然后随意调用:

 => new[] "192.168.1.100", "192.168.1.1", "192.168.1.19"
      .OrderBy(ip => StringHelper.IpAddressLabel(ip));

此外,当需要可排序标签时,这可以用作文件名或其他地方:

192.168.001.001.log
192.168.001.019.log
192.168.001.100.log

【讨论】:

【参考方案2】:

您可以将 Array.Sort 函数与我们将创建的用于比较两个 IP 的函数一起使用:

//ips is string array
Array.Sort(ips, IpCompare);

然后把这个函数放到代码里。

private static int IpCompare(string x, string y)
    
        string ip1 = x + '.', ip2 = y + '.';
        string xSection = "", ySection = "";
        for (int i = 0; i < ip1.Length && i < ip2.Length; i++)
        
            if (ip1[i] == '.' && ip2[i] == '.')
            
                if (xSection != ySection)
                    return int.Parse(xSection) - int.Parse(ySection);
                xSection = ""; // Start compare the next section
                ySection = "";
            
            else if (ip1[i] == '.') return -1; //The first section is smaller because it's length is smaller
            else if (ip2[i] == '.') return 1;
            else
            
                xSection += ip1[i];
                ySection += ip2[i];
            
        
        return 0; 
        //If we would find any difference between any section it would already return something.
        //so that mean that both IPs are the same
   

【讨论】:

【参考方案3】:

您可能会发现此功能也很有用。

public static class ExtensionMethods

  public static int CompareTo(this IPAddress x, IPAddress y)
  
    var result = x.AddressFamily.CompareTo(y.AddressFamily);
    if (result != 0)
      return result;

    var xBytes = x.GetAddressBytes();
    var yBytes = y.GetAddressBytes();

    var octets = Math.Min(xBytes.Length, yBytes.Length);
    for (var i = 0; i < octets; i++)
    
      var octetResult = xBytes[i].CompareTo(yBytes[i]);
      if (octetResult != 0)
        return octetResult;
    
    return 0;
  

【讨论】:

【参考方案4】:

您可以像这样将每个 IP 地址转换为整数...

69.52.220.44 =>

69 * 255 * 255 * 255 +
52 * 255 * 255 +
220 * 255 +
44

然后按整数表示排序。

【讨论】:

通过该计算0.0.0.2550.0.1.0 具有相同的值,它们应该不同。乘数应该是 256,而不是 255。参见 Wikipedia:“例如,四点 IP 地址 192.0.2.235 表示 32 位十进制数 3221226219”。 192.0.2.235 => 192*256*256*256 + 2*256 + 235 = 3221226219 实际上,如果你使用上面的公式,你会得到192*255*255*255 + 2*255 + 235 = 3183624745 @PatrickMevzek 是对的。一个字节有 256 个值,你应该乘以值的数量,而不是更高的值。 确保使用 32 位无符号整数!【参考方案5】:

这可能看起来像一个 hack,但它正是你所需要的:

var unsortedIps =
    new[]
    
        "192.168.1.4",
        "192.168.1.5",
        "192.168.2.1",
        "10.152.16.23",
        "69.52.220.44"
    ;

var sortedIps = unsortedIps
    .Select(Version.Parse)
    .OrderBy(arg => arg)
    .Select(arg => arg.ToString())
    .ToList();

【讨论】:

这会给你“10.152.16.23”、“192.168.1.4”、“192.168.1.5”、“192.168.2.1”、“69.5​​2.220.44” @Norbert - 请在说明之前尝试代码。我实际上在发布之前检查了结果。 @Alex 不错的解决方案,thnx Man @Alex 这真是个好主意,谢谢,它节省了我的时间 我有一个List&lt;IPAddress&gt; 并将其排序如下:lstIp = lstIp.OrderBy(i =&gt; new Version(i.ToString())).ToList();

以上是关于如何使用 c# 对 IP 地址列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何按 C# 中的特定字段对对象列表进行排序?

如何在C#中对列表进行排序[重复]

如何对一组 IP 地址 进行排序?

Python对IP地址列表排序对列表进行去重

如何按距离(以英里为单位)从 C# 中的给定纬度/经度对纬度/经度列表进行排序?

按字符串属性C#对对象列表进行排序[重复]