Late last year, I spent some time studying for the Amazon Web Services (AWS) Solutions Architect - Associate exam. In doing so, I briefly ended up covering CIDR again and the two-step math problem required to determine the number of available hosts in a CIDR IP address range.

As a recap, it works this way. Let's consider the largest VPC (Virtual Private Cloud), or a virtual network, one can define in AWS. That's 10.0.0.0/16. The way to determine the number of available host IPs is to subtract 16 (as indicated by the /16) from 32 -- a constant value. In this example, that total is also 16. We then raise 2 (the base -- another constant) to the power of 16 (the exponent/our difference), which results in 65,536 possible hosts. Because PowerShell can often distract me from AWS, let's take a look at a small function I quickly wrote out -- yes, during my AWS study time -- to do the conversion for me.

Function Get-CidrHostCount { [CmdletBinding()] Param ( [Parameter(Mandatory)] [ValidateRange(1,32)] $Cidr ) Begin { } # End Begin. Process { "Number of hosts for /$Cidr`: $([System.Math]::Pow(2,32-$Cidr))" } # End Process. End { } # End End. } # End Function: Get-CidrHostCount.

When invoked, the above Get-CidrHostCount function will accept any numeric value from 1 through 32, and determine how many hosts the CIDR range would allow. This 1 to 32 value is equivalent to the number after the forward slash in the CIDR notation. Do notice our two-step math problem. The System namespace's Math class includes a method called Pow. This method accepts two values. The first value is our base again -- 2 -- and the second number is the exponent. In the function, we use the constant value of 32 and subtract the CIDR value that's passed in when the function is invoked. These two values are then used to complete the calculation.

The below examples display a few results, but eventually return *all* the possible results.

PS > Get-CidrHostCount -Cidr 16 Number of hosts for /16: 65536 PS > Get-CidrHostCount -Cidr 20 Number of hosts for /20: 4096 PS > Get-CidrHostCount -Cidr 24 Number of hosts for /24: 256 PS > Get-CidrHostCount -Cidr 28 Number of hosts for /28: 16 PS > 1..32 | ForEach-Object { >> Get-CidrHostCount -Cidr $_ >> } Number of hosts for /1: 2147483648 Number of hosts for /2: 1073741824 Number of hosts for /3: 536870912 Number of hosts for /4: 268435456 Number of hosts for /5: 134217728 Number of hosts for /6: 67108864 Number of hosts for /7: 33554432 Number of hosts for /8: 16777216 Number of hosts for /9: 8388608 Number of hosts for /10: 4194304 Number of hosts for /11: 2097152 Number of hosts for /12: 1048576 Number of hosts for /13: 524288 Number of hosts for /14: 262144 Number of hosts for /15: 131072 Number of hosts for /16: 65536 Number of hosts for /17: 32768 Number of hosts for /18: 16384 Number of hosts for /19: 8192 Number of hosts for /20: 4096 Number of hosts for /21: 2048 Number of hosts for /22: 1024 Number of hosts for /23: 512 Number of hosts for /24: 256 Number of hosts for /25: 128 Number of hosts for /26: 64 Number of hosts for /27: 32 Number of hosts for /28: 16 Number of hosts for /29: 8 Number of hosts for /30: 4 Number of hosts for /31: 2 Number of hosts for /32: 1

Before we really wrap it up here, let's change the results as many of us would prefer to see them. Here's a mildly modified version of the function and the last above command run again.

Function Get-CidrHostCount { [CmdletBinding()] Param ( [Parameter(Mandatory)] [ValidateRange(1,32)] $Cidr ) Begin { } # End Begin. Process { "Number of hosts for /$Cidr`: $('{0:N0}' -f [System.Math]::Pow(2,32-$Cidr))" } # End Process. End { } # End End. } # End Function: Get-CidrHostCount.

PS > 1..32 | ForEach-Object { >> Get-CidrHostCount -Cidr $_ >> } Number of hosts for /1: 2,147,483,648 Number of hosts for /2: 1,073,741,824 Number of hosts for /3: 536,870,912 Number of hosts for /4: 268,435,456 Number of hosts for /5: 134,217,728 Number of hosts for /6: 67,108,864 Number of hosts for /7: 33,554,432 Number of hosts for /8: 16,777,216 Number of hosts for /9: 8,388,608 Number of hosts for /10: 4,194,304 Number of hosts for /11: 2,097,152 Number of hosts for /12: 1,048,576 Number of hosts for /13: 524,288 Number of hosts for /14: 262,144 Number of hosts for /15: 131,072 Number of hosts for /16: 65,536 Number of hosts for /17: 32,768 Number of hosts for /18: 16,384 Number of hosts for /19: 8,192 Number of hosts for /20: 4,096 Number of hosts for /21: 2,048 Number of hosts for /22: 1,024 Number of hosts for /23: 512 Number of hosts for /24: 256 Number of hosts for /25: 128 Number of hosts for /26: 64 Number of hosts for /27: 32 Number of hosts for /28: 16 Number of hosts for /29: 8 Number of hosts for /30: 4 Number of hosts for /31: 2 Number of hosts for /32: 1

And that's it -- numbers I can actually read. And yes, I finally did get back to studying for my exam.

≥ Tommy Maynard (Twitter: @thetommymaynard)

Although it gives the number of IP addresses for the CIDR, it doesn't really give you the number of hosts. In normal networking the number of hosts will be 2^H-2 because you lose one IP for the network address and one for the broadcast address.

AWS has different rules and there are five addresses that can't be used: the first four and the last one. So for AWS the formula is 2^H-5.

In both cases H = number of host bits (32 - number of subnet bits or CIDR prefix).

Hi Matt -- thank you for your comment.

I appreciate that you've clarified the distinction between the host count and available IP address count. These are absolutely two different things.

As Matt mentioned, in a traditional network the first and last IP addresses are reserved as the network address and broadcast address, respectively. He's also correct that inside an Amazon VPC, the first four and last available IP addresses are reserved. In order, these are for the network, the VPC router, DNS, AWS future use, and broadcast.

Thanks again, Matt!