I'm trying to create a subnet mask from CIDR notation eq. /8
would mean that the 8 leading bits would be 1's. I'm achieving this by left shifting (I'm working with 32 bits here) (uint)(0xffffffff << (32-8))
.
The code works fine until I get a /0
mask which leads to the code (uint)(0xffffffff << 32)
Now left shifting (uint)(0xffffffff << 31)
works as intended 10000000.00000000.00000000.00000000
.
But left shifting (uint)(0xffffffff << 32)
gives 11111111.11111111.11111111.11111111
. While expected outcome would be 00000000.00000000.00000000.00000000
.
What's the simplest way around this? Handle /0
with a if-statement and just set all to 0?
From the documentation:
That means for shifting left on a 32-bit type, only the low 5 bits in the shift count is taken. Since 32 = 0b10_0000 which needs 6 bits to store and after masking out the low 5 bits it'll become zero. So
0xffffffff << 32
is equivalent to0xffffffff << 0
To solve that you either need to shift in a higher precision
or check the shift count before shifting
The latter is better on 32-bit platforms