Today, I needed to convert a mac address to a CIDR. The lesson I learned about this is to go back to the basics instead of looking around for a quick answer. So, to the basics first.

A mac address is a 4 octet number that represents a binary position. It ranges between 1 and 255. This means something like 255.255.255.0 is represented in binary as: 1111 1111 1111 1111 1111 1111 0000 0000

It’s easier to remember the 255 number instead of all those ones and zeros. However, what’s that CIDR? Well, what’s a CIDR? A CIDR represents the mac address and how many positions there are. If you count the number above, it turns into 24 1s and 8 0s. Thus the CIDR is 24. Very simple.

Now, how do you change 240.0.0.0 to a cidr? You can go to a chart and look or we can use PowerShell. The first thing we need to do is split up this string.

"240.0.0.0" -split '\.' 

We split the string up with a split command and tell it to split it up by the . item. We use an exit \ because the . is a special character for regex. Next, we loop through this list of octets with a foreach-object loop.

$Mask -split '\.' | ForEach-Object {
        
    }

Then we break down each octet into a binary number. We do this with a system.convert and tell it the number we bytes we want which is 2.

[System.Convert]::ToString($_, 2)

We then pad that information because sometimes 0s will produce more useless items.

([System.Convert]::ToString($_, 2).PadLeft(8, '0'))

The code above will give us the 1s and 0s of the binary number. Now we need to count the ones. We do this by converting the string to a char array with at .toochararray(). We search the string with a where-object for the number 1 and finally count it.

(([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count

Now we need to add each item up. We do this by adding a variable before the loop set to 0 and then add the variable to the variable and the count. Finally, after the loop, display the information.

$Cidr = 0
    $Mask -split '\.' | ForEach-Object {
        $Cidr = $Cidr + (([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count
    }
    $Cidr

That’s it yall! We count the number of 1s. That will give us our cidr count.

Script

Have fun with the script!

function ConvertFrom-SHDIPv4MaskToCidr {
    param (
        [string]$Mask
    )
    $Cidr = 0
    $Mask -split '\.' | ForEach-Object {
        $Cidr = $Cidr + (([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count
    }
    $Cidr
}