因此,我在对 IPv4 地址进行排序时遇到了难题,不知道某些晦涩难懂的网络文档中是否有固定的规则。我是否只对原始地址进行直接排序(例如将 IP 地址转换为 32 位数字然后进行排序),我是否通过某些数学公式将 CIDR 考虑在内,我是否只通过 CIDR 进行排序(就好像我在比较网络大小而不是直接比较地址一样)?
即,在普通数学中,我们会做一些类似的事情-1 < 0 < 1
来表示优先顺序。假设,,,,10.1.0.0/16
和,172.16.0.0/12
优先顺序是什么?192.168.1.0/24
192.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
。