Given an IP address and subnetmask, how do I calculate the CIDR?
256 - 240 = 16 = 2**4, 32 - 4 = 28
It is not really a C# question.
To get a net address from an IP and mask you can apply bytewise and
to the IP and mask. You can get bytes from a string using IPAddress.Parse()
and IPAddress.GetAddressBytes()
.
I had to do the same thing, no new info but this snippet may come in handy for the next person looking for a way to do this in C#. note that this method only counts the number of consecutive 1s, and leaves you the work of appending it to the IP.
public class IPAddressHelper
{
public static UInt32 SubnetToCIDR(string subnetStr)
{
IPAddress subnetAddress = IPAddress.Parse(subnetStr);
byte[] ipParts = subnetAddress.GetAddressBytes();
UInt32 subnet = 16777216 * Convert.ToUInt32(ipParts[0]) + 65536 * Convert.ToUInt32(ipParts[1]) + 256 * Convert.ToUInt32(ipParts[2]) + Convert.ToUInt32(ipParts[3]);
UInt32 mask = 0x80000000;
UInt32 subnetConsecutiveOnes = 0;
for (int i = 0; i < 32; i++)
{
if (!(mask & subnet).Equals(mask)) break;
subnetConsecutiveOnes++;
mask = mask >> 1;
}
return subnetConsecutiveOnes;
}
}
Keep it simple!
This works for IPv4 only, but since IPv6 does only support CIDR like /64
in fe80::1ff:fe23:4567:890a/64
calculations like that are unnecessary there.
All you need for an IPv4 network mask:
int cidr = Convert.ToString(mask.Address, 2).Count( o => o == '1');
Explanation based on the given example:
IPAddress mask = new IPAddress(new byte[] { 255, 255, 255, 240 });
// maskBinAsString = 11110000111101001111111111111111
string maskBinAsString = Convert.ToString(mask.Address, 2);
// cidr = 28
int cidr = Convert.ToString(mask.Address, 2).Count( o=> o == '1');