c код для действительной маски сети

Есть ли способ проверить, что 32-битная маска сети действительна или не использует побитовый оператор?

Я должен проверить со стороны msb, что '1' находятся в непрерывном потоке или нет. Например, 11111111.0.0.0 (255.0.0.0) является действительным, а 11111101.0.0.0 (253.0.0.0) - нет.

2 ответа

Решение

Первое, что нужно сделать, это проверить, что маска сети не равна нулю (неприятный крайний случай). Учитывая, что это нормально, вам нужно принять побитовое обратное.

uint32_t y = ~x;

Затем добавьте один

uint32_t z = y + 1;

Тогда если x была правильная маска сети, в ней будет установлено не более 1 бита.

Чтобы проверить это, просто и z с z - 1, который случается y, Результат будет нулевым, если все в порядке, ненулевым в противном случае.

valid = (z & y) == 0;

Чтобы проверить недействительную маску сети, вы можете использовать следующий простой алгоритм:

mask & (~mask >> 1)

Это даст оценку 1 для недопустимой маски сети и 0 для действительной маски сети.

Действительная сетевая маска не может иметь ноль с одним справа от него. Все нули должны иметь еще один ноль справа от него или быть битом 0. Если вы возьмете те, которые дополняют (~) сетевой маски, которая имеет ноль с единицей справа от нее, и сдвинете ее вправо на одну битовую позицию, вы выровняете единицу в сетевой маске с единицей в сдвинутом дополнении сетевой маски. 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;
    }
}
Другие вопросы по тегам