我有没有办法检查32位网络掩码是否有效使用按位运算符?
我必须从msb侧检查"1"是否在连续流中.例如11111111.0.0.0(255.0.0.0)有效但11111101.0.0.0(253.0.0.0)无效.
Tom*_*ner 15
首先要做的是检查网络掩码是否为非零(一个讨厌的边缘情况).鉴于这是可以的,您需要采用按位反转.
uint32_t y = ~x;
Run Code Online (Sandbox Code Playgroud)
然后添加一个
uint32_t z = y + 1;
Run Code Online (Sandbox Code Playgroud)
然后,如果x是一个合适的网络掩码,那么最多将设置1位.
为了测试它,简单地z用z - 1,恰好是y.如果一切正常,结果将为零,否则为非零.
valid = (z & y) == 0;
Run Code Online (Sandbox Code Playgroud)
小智 7
要检查无效的网络掩码,您可以使用以下简单算法:
mask & (~mask >> 1)
Run Code Online (Sandbox Code Playgroud)
对于无效的网络掩码,这将评估为 1,对于有效的网络掩码评估为 0。
一个有效的网络掩码不能有一个右边有一个 0 的零。所有零的右侧必须有另一个零或位 0。如果您取网络掩码的补码 (~),该网络掩码有一个零,其右侧有一个 1,并将其向右移动一位位置,您将网络掩码中的一与网络掩码的移位补码中的一对齐。将这两个值进行 AND 运算将产生一个表示无效网络掩码的值。
如果采用网络字节顺序,请确保在应用此算法之前使用 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;
}
}
Run Code Online (Sandbox Code Playgroud)