对 IPv4 地址进行排序

对 IPv4 地址进行排序

因此,我在对 IPv4 地址进行排序时遇到了难题,不知道某些晦涩难懂的网络文档中是否有固定的规则。我是否只对原始地址进行直接排序(例如将 IP 地址转换为 32 位数字然后进行排序),我是否通过某些数学公式将 CIDR 考虑在内,我是否只通过 CIDR 进行排序(就好像我在比较网络大小而不是直接比较地址一样)?

即,在普通数学中,我们会做一些类似的事情-1 < 0 < 1来表示优先顺序。假设,,,,10.1.0.0/16和,172.16.0.0/12优先顺序是什么?192.168.1.0/24192.168.1.42

答案1

上次我这样做时,大致是这样实现的(为了清楚起见,省略了验证和错误检查):

(addressA, maskA) = split('/', a);
(addressB, maskB) = split('/', b);
ipCmp = inet_aton(addressB) - inet_aton(addressA);
if (ipCmp > 0) {
    return -1;
} else if (ipCmp < 0) {
    return 1;
} else {
    if (maskA < maskB) {
        return 1;
    } else if (maskA > maskB) {
        return -1;
    } else {
        return 0;
    }
}

给定输入数组,{ 10.0.1.0/24, 10.0.0.0/24, 10.0.0.0/8 }这应该产生{ 10.0.0.0/8, 10.0.0.0/24, 10.0.1.0/24 }

编辑以添加:据我所知,没有“普遍接受”的方法,上述方法只是对我必须完成的任务最有用的方法。使用 inet_aton 的原因是 IP 地址只是格式略有不同的整数。将它们作为整数进行比较,您会得到一个有用的排序。

答案2

您可以使用以下命令对 IP 地址进行排序:

sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 ips.txt

这是啥?

它使用带有-n参数的排序来告诉排序我们将进行数字排序。

但是我们的数字由 4 个子数字(IP 地址的实际八位字节)表示,它们之间用点.( -t .) 分隔。因此,让我们进行排序,首先按第一个字段排序,并且只按第一个字段排序 ( -k 1,1),然后按第二个字段排序,-k 2,2并且只按第二个字段排序 ( ),依此类推 ( ) -k 3,3 -k 4,4

答案3

哦,好的,那么这是你的 CS 作业吗?

然后按你喜欢的任何方式排序;没有技术原因会偏爱一种排序方案而不是另一种。Pacey 的想法很好,但如果你也想考虑掩码,我可能会先按掩码大小排序,然后使用 Pacey 的方案对掩码最大的地址进行排序,然后对掩码第二大的地址进行排序,直到对 /32 进行排序。它没有任何技术含义,但似乎比按地址排序更容易证明。然后决定这192.168.0.64/29比……更重要192.168.0.64/32

相关内容