1

I need to calculate the prefix length of a IPv4 network mask. My first naive approach is

int calculate_prefix_length (uint32_t address) {
  int set_bits;
    for (set_bits = 0; address; address >>= 1) {
      set_bits += address & 1;
    }
  return set_bits;
}

This is probably not very fast. is there a better solution?

TNA
  • 2,595
  • 1
  • 14
  • 19

2 Answers2

2

Netmak usually have 'n' number of '1's followed by 32-'n' zeros. so count the zeros first, subtract from 32 gives the number of '1's. Or you can count the number of '1's first if your network is class A. The following works faster for class 'C' networks

int calculate_prefix_length (uint32_t address) {
   int zero_bits;
   for (zero_bits = 0; (address & 1) == 0; address >>= 1, zero_bits++);
   return (32 - zero_bits);
}
0

You can also avoid branching by calculating count of bits set:

    constexpr uint8_t numberOfSetBits(uint32_t i)
    {
        i = i - ((i >> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
        i = (i + (i >> 4)) & 0x0F0F0F0F;
        return (i * 0x01010101) >> 24;
    }

See explanation and more at https://stackoverflow.com/a/109025/4880243

AgainPsychoX
  • 1,527
  • 1
  • 16
  • 20