1
$\begingroup$

In looking for a programming function to validate an IP address within a subnet, I had to calculate the subnet mask from a given CIDR bitmask value ie. 192.168.0.0/24, the value 24 in this example.

The first step is to convert the bitmask value (24) into an unsigned 32bit integer. I found this on the internet (specific to our 24 bitmask example): mask = (( 2^24 ) - 1) * ( 2^(32-24) ). This gives me an integer value of 4,294,967,040 which is exactly the binary number I am looking for where the first 24 bits are 1, while the remaining bits are 0 11111111.11111111.11111111.00000000. Obviously, this works for any bitmask value 0-32.

I would like to understand why this works: mask = (( 2^bitmask ) - 1) * (2^( 32-bitmask ))

$\endgroup$
1
$\begingroup$

The binary expansion of $2^n-1$ consists of $n$ ones. This is because the binary expansion of $2^n$ consists of a one followed by $n$ zeroes. This is similar to $10^3-1 = 999$ in decimal.

If we want these $n$ bits to be the left $n$ bits out of $m$ bits, then we need to add $m-n$ zeroes to the right. This is the same as multiplying everything by $2^{n-m}$. Compare $100 \cdots 54 = 5400$. This operation is usually known as left shift, and many languages support it natively. For example, in C you would use the following code to generate the mask:

((1 << 24) - 1) << (32-24)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.