我有什么方法可以使用按位运算符检查32位网络掩码是否有效?
我必须从msb方面检查'1'是否在连续流中。 例如11111111.0.0.0(255.0.0.0)有效 但是11111101.0.0.0(253.0.0.0)不是。
答案 0 :(得分:15)
要做的第一件事是检查网络掩码是否为非零(一个讨厌的边缘情况)。鉴于这是可以的,你需要采用按位反转。
uint32_t y = ~x;
然后添加一个
uint32_t z = y + 1;
如果x
是一个合适的网络掩码,那么最多只能设置1位。
要对此进行测试,只需z
与z - 1
进行测试,恰好是y
。如果一切正常,结果将为零,否则为非零。
valid = (z & y) == 0;
答案 1 :(得分:3)
要检查无效的网络掩码,您可以使用以下简单算法:
mask & (~mask >> 1)
对于无效的网络掩码,这将评估为1,对于有效的网络掩码,评估为0。
有效的网络掩码不能为零,右边有一个。所有的零必须在其右边有另一个零或位为0.如果你取一个零掩码的补码(〜),其右边有一个零,并将它向右移一位位置,您将在网络掩码中将一个与网络掩码的移位一个补码中的一个对齐。并且将这两个值组合在一起将产生一个表示无效网络掩码的值。
在应用此算法(如果它是网络字节顺序)之前,请确保使用ntohl()将网络掩码转换为主机字节顺序。此外,如果要排除它们,则需要对0xffffffff和0x00000000进行特殊检查。
注意:由于C的运算符的优先级和关联性规则,算法中显示的括号不是必需的,但我已添加它们以使代码更容易理解,以防您不在t始终记住优先级和关联性规则。
int is_netmask_valid(uint32_t mask)
{
if (mask == 0) return 0;
if (mask & (~mask >> 1)) {
return 0;
} else {
return 1;
}
}