9

I there any way to check that 32 bit netmask is valid or not using bitwise operator?

I have to check from msb side that '1' are in continuous stream or not. eg 11111111.0.0.0 (255.0.0.0)is valid but 11111101.0.0.0 (253.0.0.0) is not.

4

2 回答 2

16

首先要做的是检查网络掩码是否非零(一个令人讨厌的边缘情况)。鉴于这没问题,您需要进行按位求逆。

uint32_t y = ~x;

然后加一个

uint32_t z = y + 1;

然后,如果x是一个正确的网络掩码,则最多会设置 1 位。

z简单地用来测试它z - 1,它恰好是y。如果一切正常,结果将为零,否则为非零。

valid = (z & y) == 0;
于 2013-07-01T09:33:57.033 回答
9

要检查无效的网络掩码,您可以使用以下简单算法:

mask & (~mask >> 1)

对于无效的网络掩码,这将评估为 1,对于有效的网络掩码,评估为 0。

有效的网络掩码不能在其右侧有一个 0 和一个 1。所有零都必须在其右侧有另一个零或为位 0。如果您取一个网络掩码的补码 (~),该网络掩码的右侧有一个零和一个 1,并将其向右移动一位,您会将网络掩码中的 1 与网络掩码的移位补码中的 1 对齐。将这两个值“与”在一起将产生一个表示无效网络掩码的值。

如果它是网络字节顺序,请确保在应用此算法之前使用 ntohl() 将网络掩码转换为主机字节顺序。此外,如果您希望排除它们,则需要对 0xffffffff 和 0x00000000 进行特殊检查。

注意:由于 C 对运算符的优先级和关联性规则,算法中显示的括号不是必需的,但我添加了它们以使代码更易于理解,以防您不总是记住优先级和关联性规则。

int is_netmask_valid(uint32_t mask)
{
    if (mask == 0) return 0;
    if (mask & (~mask >> 1)) {
        return 0;
    } else {
        return 1;
    }
}
于 2017-08-11T17:18:04.373 回答