有效网络掩码的c代码

问题描述 投票:0回答:3

我有什么方法可以使用按位运算符检查 32 位网络掩码是否有效?

我必须从 MSB 端检查“1”是否处于连续流中。 例如 11111111.0.0.0 (255.0.0.0) 有效 但 11111101.0.0.0 (253.0.0.0) 不是。

c networking
3个回答
18
投票

首先要做的是检查网络掩码是否非零(令人讨厌的边缘情况)。既然这样就可以了,你需要按位求逆。

uint32_t y = ~x;

然后添加一个

uint32_t z = y + 1;

那么如果

x
是一个正确的网络掩码,则最多将设置 1 位。

为了测试这一点,只需将

z
z - 1
相结合,恰好是
y
。如果一切正常,结果将为零,否则结果将不为零。

valid = (z & y) == 0;

10
投票

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

mask & (~mask >> 1)

对于无效的网络掩码,其计算结果为 1;对于有效的网络掩码,其计算结果为 0。

有效的网络掩码不能有 0 且其右侧有 1。 所有零的右侧都必须有另一个零,或者为位 0。如果您采用右侧有一个 0 的网络掩码的补码 (~),并将其向右移动一位位置,您将网络掩码中的 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;
    }
}

0
投票

~mask & -mask
呢?尽管如此, mask == 0 。 对于右侧的
mask = 0b11110000
(1 后跟 0),您将得到:

~mask = 0b00001111
-mask = 0b00010000

然后

~mask & -mask == 0

对于错误的

mask = 0b11010000
:

~mask = 0b00101111
-mask = 0b00110000

然后

~mask & -mask == 0b00100000 (!= 0)
© www.soinside.com 2019 - 2024. All rights reserved.