Get-PowerIP2CIDR.ps1

<#
.SYNOPSIS
Converts provided range to CIDR or splits provided CIDR to subnet blocks.
.DESCRIPTION
Function utilized by Test-PowerPing to convert range to CIDR.
.NOTES
Author: Hunter Hirsch
#>

## Tables to assist with increment calculations
$zfact = 2,4,8,16,32,64,128
$rincr = @{
    '32' = 1
    '0,8,16,24' = 255
    '1,9,17,25' = 128
    '2,10,18,26' = 64
    '3,11,19,27' = 32
    '4,12,20,28' = 16
    '5,13,21,29' = 8
    '6,14,22,30' = 4
    '7,15,23,31' = 2
    }
$rbases = @{
    '0,1,2,3,4,5,6,7' = 0
    '8,9,10,11,12,13,14,15' = 1
    '16,17,18,19,20,21,22,23' = 2
    '24,25,26,27,28,29,30,31' = 3
    }
## Function to determine increment increase between blocks when increasing block size (small to large)
function Get-ppblkup {
    Param(
    [Parameter (Mandatory)]
    [byte]
    $bfact,
    [Parameter (Mandatory)]
    [uint32]
    $last
    )
    $cfact = $null
    if ($bfact-ne 0){
        for (($i = $bfact),($k = 2); ($i/$k).GetType().name -ne 'Double' -and $k -le 128; $k = $k*2){
            $cfact = $k
            }
        }
    Else{
        $last++
        if ($last -lt 256){
            for ($i = 0; $last -ge $zfact[$i] -and $i -le 6; $i++){
                $cfact = $zfact[$i]
                }
            }
        Else{
            $cfact = 255
            }
        }
    return $cfact
    }
## Function to determine increment difference when decreasing block size (large to small)
function Get-ppblkdwn {
    Param(
    [Parameter (Mandatory)]
    [byte]
    $s,
    [Parameter (Mandatory)]
    [byte]
    $e,
    [Parameter (Mandatory)]
    [uint32]
    $dif
    )
    $fact = get-ppblkup -bfact $s -last $e
    if ($s -eq 0){
        $dif++
        }
    while ($fact -gt $dif){
        $fact = $zfact[(($zfact.IndexOf($fact)) -1)]
        }
    return $fact
    }
## Function to convert range to CIDR with fewest possible blocks
function Get-PPCIDRMin{
    Param(
    [Parameter (Mandatory)]
    [byte[]]
    $Start,
    [Parameter (Mandatory)]
    [byte[]]
    $End,
    [Parameter (Mandatory)]
    [int32]
    $base
    )
Begin{
    if ($Start[3]%2 -ne 0){
        $odd = $true
        }
    if ($base -eq 3){
        [uint32]$3dif = $End[3] - $Start[3]
        }
    Else{
        $tblk = $base+1
        $TB = $true
        if ($End[$base]%2 -ne 0){
            while ($tblk -lt 4){
                if ($End[$tblk] -ne 255){
                    $TB = $false
                    }
                $tblk++
                }
            }
        Else{
            $TB = $false
            }
        }
    if ($odd -and $base -lt 3){
        $cidque.Enqueue([string][ipaddress] $Start + '/32')
        $odd = $null
        if ($Start[3] -lt 255){
            $Start[3]++
            }
        Else{
            if ($Start[2] -lt 255){
                $Start[2]++
                }
            Else{
                $Start[2] = 0
                if ($Start[1] -lt 255){
                    $Start[1]++
                    }
                Else{
                    $Start[1] = 0
                    if ($Start[0] -lt 255){
                        $Start[0]++
                        }
                    }
                }
            $Start[3] = 0
            }
        }
    if ($base -lt 3 -and $Start[3] -ne 0){
        while ($Start[3] -ne 0){
            $plus = get-ppblkup -bfact $Start[3] -last 255
            $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[3]
            $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
            if (($Start[3] + $plus) -lt 255){
                $Start[3] = $Start[3] + $plus
                }
            Else{
                $Start[3] = 0
                if ($Start[2] -lt 255){
                    $Start[2]++
                    }
                Else{
                    $Start[2] = 0
                    if ($Start[1] -lt 255){
                        $Start[1]++
                        }
                    Else{
                        $Start[1] = 0
                        if ($Start[0] -lt 255){
                            $Start[0]++
                            }
                        }
                    }
                }
            }
        }
    }
Process{
    if ($base -lt 3){
        for ($i = 2;!$stop; $i--){
            if ($Start[$i] -ne 0 -and $base -lt $i){
                while ($start[$i] -ne 0){
                    if ($Start[$i]%2 -ne 0){
                        $afact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($i+1)]
                        $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                        if ($Start[$i] -lt 255){
                            $Start[$i]++
                            }
                        Else{
                            $Start[$i] = 0
                            if ($i -gt 0){
                                if ($Start[($i-1)] -lt 255){
                                    $Start[($i-1)]++
                                    }
                                Else{
                                    $Start[($i-1)] = 0
                                    if ($i -gt 1){
                                        if ($Start[($i-2)] -lt 255){
                                            $Start[($i-2)]++
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    if ($start[$i] -ne 0){
                        $plus = get-ppblkup -bfact $Start[$i] -last 255
                        $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[$i]
                        $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                        if (($Start[$i] + $plus) -lt 255){
                            $Start[$i] = $Start[$i] + $plus
                            }
                        Else{
                            $Start[$i] = 0
                            if ($i -gt 0){
                                if ($Start[($i-1)] -lt 255){
                                    $Start[($i-1)]++
                                    }
                                Else{
                                    $Start[($i-1)] = 0
                                    if ($i -gt 1){
                                        if ($Start[($i-2)] -lt 255){
                                            $Start[($i-2)]++
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            Elseif ($base -eq $i){
                $bdif = $End[$i] - $Start[$i]
                if ($Start[$i]%2 -ne 0 -and $bdif -gt 0){
                    $afact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($i+1)]
                    $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                    if ($Start[$i] -lt 255){
                        $Start[$i]++
                        }
                    Else{
                        $Start[$i] = 0
                        if ($i -gt 0){
                            if ($Start[($i-1)] -lt 255){
                                $Start[($i-1)]++
                                }
                            Else{
                                $Start[($i-1)] = 0
                                if ($i -gt 1){
                                    if ($Start[($i-2)] -lt 255){
                                        $Start[($i-2)]++
                                        }
                                    }
                                }
                            }
                        }
                    $bdif = $End[$i] - $Start[$i]
                    }
                if ($End[$i]%2 -ne 0 -and $TB){
                    $bdif = ($End[$i] +1) - $Start[$i]
                    }
                while ($bdif -gt 0){
                    if ($bdif -gt 1 -and $TB){
                        $plus = get-ppblkdwn -s $Start[$i] -e $End[$i] -dif $bdif
                        $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[$i]
                        $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                        if (($Start[$i] + $plus) -lt 255){
                            $Start[$i] = $Start[$i] + $plus
                            }
                        Else{
                            $Start[$i] = 255
                            }
                        if ($End[$i]%2 -ne 0){
                            $bdif = ($End[$i] +1) - $Start[$i]
                            if ($bdif -eq 1){
                                $bdif = 0
                                }
                            }
                        Else{
                            $bdif = $End[$i] - $Start[$i]
                            }
                        }
                    if ($bdif -gt 1 -and !$TB){
                        if ($End[$i] -eq 255){
                            [byte]$iEnd = 254
                            }
                        Else{
                            $iEnd = $End[$i]
                            }
                        if ($Start[$i] -eq 0){
                            $iEnd--
                            }
                        $plus = get-ppblkdwn -s $Start[$i] -e $iEnd  -dif $bdif
                        $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[$i]
                        $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                        $Start[$i] = $Start[$i] + $plus
                        $bdif = $End[$i] - $Start[$i]
                        }
                    if ($bdif -eq 1){
                        if ($Start[$i]%2 -ne 0){
                            $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($i+1)]
                            $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                            if ($Start[$i] -lt 255){
                                $Start[$i]++
                                }
                            if ($TB){
                                $stop = $true
                                }
                            }
                        Else{
                            if ($TB){
                                $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 2})).split(',')[$i]
                                $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                                $Start[$i] = $Start[$i]+2
                                $stop = $true
                                }
                            Else{
                                $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($i+1)]
                                $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                                $Start[$i]++
                                }
                            }
                        $bdif = 0
                        }
                    }
                if ($TB -and $bdif -eq 0){
                    $stop = $true
                    }
                }
            if (!$TB -and $base -eq $i){
                if ($base -eq 0 -and $end[3] -eq 255){
                    $jcheck = $true
                    }
                for ($j = $base+1; $j -lt 3; $j++){
                    $jdif = $End[$j] - $Start[$j]
                    while ($Start[$j] -ne $End[$j]){
                        if ($jdif -gt 1){
                            if ($End[($j+1)] -ne 255){
                                $jEnd = $End[$j] -1
                                if ($Start[$j] -eq 0 -and $End[$j]%2 -ne 0){
                                    $jEnd--
                                    }
                                }
                            Else{
                                if ($jcheck -or $j -eq 2){
                                    $jEnd = $End[$j]
                                    if ($jEnd%2 -ne 0){
                                        $jdif++
                                        }
                                    }
                                Else{
                                    $jEnd = $End[$j] -1
                                    if ($Start[$j] -eq 0 -and $End[$j]%2 -ne 0){
                                        $jEnd--
                                        }
                                    }
                                }
                            $plus = get-ppblkdwn -s $Start[$j] -e $jEnd -dif $jdif
                            $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[$j]
                            $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                            $Start[$j] = $Start[$j] + $plus
                            $jdif = $End[$j] - $Start[$j]
                            }
                        if ($jdif -eq 1){
                            if ($End[$j]%2 -ne 0){
                                if ($End[($j+1)] -eq 255){
                                    if ($jcheck -or $j -eq 2){
                                        $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 2})).split(',')[($j)]
                                        }
                                    else{
                                        $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($j+1)]
                                        }
                                    }
                                Else{
                                    $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($j+1)]
                                    }
                                $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                                $Start[$j] = $End[$j]
                                if ($j -eq 2 -or ($End[($j+1)] -eq 255 -and $End[3] -eq 255)){
                                    $j = 4
                                    }
                                }
                            Else{
                                $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($j+1)]
                                $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                                $Start[$j]++
                                }
                            }
                        if ($jdif -le 0){
                            if ($End[$j]%2 -eq 0 -and ($End[($j+1)] -eq 255 -and $End[3] -eq 255) -and $j -lt 2){
                                $Start[$j] = $End[$j]
                                $ifact = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($j+1)]
                                $cidque.Enqueue([string][ipaddress] $Start + "/$ifact")
                                }
                            if ($j -eq 2 -or ($End[($j+1)] -eq 255 -and $End[3] -eq 255)){
                                $j = 4
                                }
                            }
                        }
                    }
                If ($End[3] -ne 255){
                    $3dif = $End[3]
                    }
                else{
                    $test = $Start.Clone()
                    $test[3] = 255
                    if ([string][ipaddress] $test -eq [string][ipaddress] $End -and $End[2]%2 -eq 0){
                        $cidque.Enqueue([string][ipaddress] $Start + '/24')
                        }
                    $test = $null
                    }
                $stop = $true
                }
            }
        }
    if ($3dif){
        if ($3dif -eq 1){
            if ($odd){
                $cidque.Enqueue([string][ipaddress] $Start + '/32')
                $cidque.Enqueue([string][ipaddress] $End + '/32')
                }
            Else{
                $cidque.Enqueue([string][ipaddress] $Start + '/31')
                }
            }
        Else{
            if ($odd -and $base -eq 3){
                $cidque.Enqueue([string][ipaddress] $Start + '/32')
                $Start[3]++
                $3dif--
                }
            if ($3dif -eq 1){
                $cidque.Enqueue([string][ipaddress] $Start + '/31')
                }
            Else{
                while ($3dif -gt 0){
                    if ($3dif -gt 1){
                        if ($zfact -contains ($3dif+1)){
                            $3dif++
                            if ($end[3] -lt 255){
                                $end[3]++
                                }
                            $3end = $true
                            }
                        $plus = get-ppblkdwn -s $Start[3] -e $End[3] -dif $3dif
                        $afact = ($rincr.Keys.Where({$rincr.$_ -eq $plus})).split(',')[3]
                        $cidque.Enqueue([string][ipaddress] $Start + "/$afact")
                        if (($Start[3] + $plus) -lt 255){
                            $Start[3] = $Start[3] + $plus
                            }
                        Else{
                            $Start[3] = 255
                            }
                        if ($End[3] -eq 255){
                            $3dif = 256 - $Start[3]
                            if ($3dif -eq 1){
                                $3dif = 256
                                }
                            }
                        Else{
                            $3dif = $End[3] - $Start[3]
                            }
                        }
                    if ($3dif -eq 1){
                        if (($Start[3]/2).GetType().Name -eq 'Double'){
                            $cidque.Enqueue([string][ipaddress] $Start + '/32')
                            $cidque.Enqueue([string][ipaddress] $End + '/32')
                            }
                        Else{
                            $cidque.Enqueue([string][ipaddress] $Start + '/31')
                            }
                        $3dif = 0
                        }
                    Elseif (!$3end -and $3dif -eq 0){
                        $cidque.Enqueue([string][ipaddress] $Start + '/32')
                        }
                    Elseif ($3dif -eq 256){
                        $3dif = 0
                        }
                    }
                }
            }
        }
    Elseif ($3dif -eq 0 -and $End[3] -eq 0){
        $cidque.Enqueue([string][ipaddress] $Start + '/32')
        }
    }
End{
    }
}
## Function to split range/CIDR into sub blocks
function Get-PowerIP2CIDR{
[CmdletBinding()]
[OutputType([system.collections.arraylist])]
    Param(
        [Parameter(Mandatory)]
        [string]
        $Begin,
        [Parameter(Mandatory)]
        [string]
        $Finish,
        [Parameter(Mandatory)]
        [string]
        $factor,
        [Parameter()]
        [switch]
        $full
        )
Begin{
    $cidque = [System.Collections.Queue]::new()
    $cidlist = [System.Collections.ArrayList]::new()
    [byte[]]$starr = $Begin.Split('.')
    [byte[]]$edarr = $Finish.split('.')
    [string]$adbal = ($edarr[0] - $starr[0]),($edarr[1] - $starr[1]),($edarr[2] - $starr[2]),($edarr[3] - $starr[3])
    $adbal = $adbal.Replace(" ",'')
    if ($adbal[0] -eq '-' -or $adbal -match "^[0]{1,3}-"){
        [byte[]]$starr = $Finish.split('.')
        [byte[]]$edarr = $Begin.Split('.')
        }
    $rbase = 0
    for (($i=0); $starr[$i] -eq $edarr[$i]; $i++){
        $rbase++
        }
    if (1..31 -contains $factor){
        $basediff = ($edarr[$rbase] - $starr[$rbase]) +1
        $plustable = $rincr.Values | Sort-Object
        $fplus = $rincr.Keys.Where({$_.split(',') -contains $factor}) | ForEach-Object {$rincr.$_}
        for ($i = 0; $basediff -ge $plustable[$i] -and $i -le 8; $i++){
            if ($basediff -gt 1){
                $fmax = ($rincr.Keys.Where({$rincr.$_ -eq $plustable[$i]})).split(',')[$rbase]
                }
            Else{
                $fmax = ($rincr.Keys.Where({$rincr.$_ -eq 255})).split(',')[($rbase+1)]
                }
            }
        if ([int32]$factor -eq $fmax){
            if ($starr[$rbase]%2 -ne 0 -and $plustable -contains $basediff){
                $invalidfactor = $true
                }
            Else{
                if ($basediff -eq $fplus){
                    for ($i = $rbase +1; $i -le 3; $i++){
                        if ($starr[$i] -ne 0 -or $edarr[$i] -ne 255){
                            $invalidfactor = $true
                            }
                        }
                    }
                if ($basediff -gt $fplus){
                    $fmaxbase = $starr.Clone()
                    while ($fmaxbase[$rbase]%$fplus -ne 0){
                        $fmaxbase[$rbase]++
                        if ($fmaxbase[$rbase] -eq 255){
                            $invalidfactor = $true
                            $fmaxbase[$rbase] = $fplus
                            }
                        }
                    if (!$invalidfactor){
                        if ($edarr[$rbase] -eq 255 -and $rbase -lt 3){
                            for ($i = $rbase + 1; $i -le 3; $i++){
                                if ($edarr[$i] -ne 255){
                                    $invalidfactor = $true
                                    }
                                }
                            }
                        Else{
                            if (($fmaxbase[$rbase] + $fplus) -gt $edarr[$rbase]){
                                $invalidfactor = $true
                                }
                            if (($fmaxbase[$rbase] + $fplus) -eq $edarr[$rbase] -and $rbase -lt 3){
                                for ($i = $rbase +1; $i -le 3; $i++){
                                    if ($starr[$i] -ne 0){
                                        $invalidfactor = $true
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        if ([int32]$factor -lt $fmax -or !$fmax -or $invalidfactor){
            Throw Write-Output "Divider block size: $factor greater than provided Start/End range. Update parameters and try again."
            }
        for ($i = $rbase; $i -le 3; $i++){
            if (($rbases.Keys.Where({$rbases.$_ -eq $i})).split(',') -contains $factor){
                $fbase = $i
                }
            }
        if ($starr[3]%2 -ne 0){
            $cidque.Enqueue([string][ipaddress] $starr + '/32')
            if ($starr[3] -lt 255){
                $starr[3]++
                }
            Else{
                $starr[3] = 0
                if ($starr[2] -lt 255){
                    $starr[2]++
                    }
                Else{
                    $starr[2] = 0
                    if ($starr[1] -lt 255){
                        $starr[1] ++
                        }
                    Else{
                        $starr[1] = 0
                        if ($starr[0] -lt 255){
                            $starr[0]++
                            }
                        }
                    }
                }
            }
        if ($starr[$fbase]%$fplus -eq 0){
            if ($starr[$fbase] -ne 255){
                $validstart = $true
                for ($i = $fbase + 1; $i -le 3; $i++){
                    if ($starr[$i] -ne 0){
                        $validstart = $false
                        }
                    }
                }
            }
        if (!$validstart){
            $bstarr = $starr.Clone()
            for ($i = 3;$i -ge $fbase; $i--){
                if ($i -ne $fbase){
                    $bstarr[$i] = 255
                    }
                Else{
                    if ($bstarr[$i] -ne 0){
                        if ($bstarr[$i]%$fplus -ne 0){
                            while ($bstarr[$i]%$fplus -ne 0 -and !$cap){
                                if ($bstarr[$i] -lt 255){
                                    $bstarr[$i]++
                                    }
                                Else{
                                    $bstarr[$i] = 255
                                    $cap = $true
                                    }
                                }
                            }
                        Else{
                            if (($bstarr[$i] + $fplus) -lt 255){
                                $bstarr[$i] = $bstarr[$i] + $fplus
                                }
                            Else{
                                $bstarr[$i] = 255
                                }
                            }
                        }
                    Else{
                        if ($fplus -ne 255){
                            $bstarr[$i] = $bstarr[$i] + $fplus -1
                            }
                        Else{
                            $bstarr[$i] = 255
                            }
                        }
                    }
                }
            if ($bstarr[$fbase]%2 -eq 0 -and $bstarr[$fbase] -ne $starr[$fbase]){
                $bstarr[$fbase]--
                }
            $fstart = $bstarr
            }
        $validend = $true
        for ($i = $fbase; $i -le 3; $i++){
            if ($i -eq $fbase){
                if ($edarr[$i]%2 -eq 0){
                    $validend = $false
                    }
            Elseif ($edarr[$i] -ne 255){
                    if ($fplus -eq 255){
                        $validend = $false
                        }
                    Else{
                        $tplus = $fplus
                        $tpt = $false
                        while ($tplus -lt 255){
                            if ($edarr[$i] -eq ($tplus-1)){
                                $tpt = $true
                                }
                            $tplus = $tplus + $fplus
                            }
                        if (!$tpt){
                            $validend = $false
                            }
                        }
                    }
                }
            Else{
                if ($edarr[$i] -ne 255){
                    $validend = $false
                    }
                }
            }
        if ($validend){
            $bedarr = $edarr.Clone()
            if ($bedarr[$fbase] -lt 255){
                $bedarr[$fbase]++
                }
            Else{
                $bedarr[$fbase] = 0
                if ($bedarr[($fbase-1)] -lt 255){
                    $bedarr[($fbase-1)]++
                    }
                Else{
                    $bedarr[($fbase-1)]=0
                    if ($bedarr[($fbase-2)] -lt 255){
                        $bedarr[($fbase-2)]++
                        }
                    Else{
                        $bedarr[($fbase-2)]=0
                        if ($bedarr[($fbase-3)] -lt 255){
                            $bedarr[($fbase-3)]++
                            }
                        Else{
                            $bedarr[($fbase-3)] = 0
                            }
                        }
                    }
                }
            for ($i = $fbase+1; $i -le 3; $i++){
                $bedarr[$i] = 0
                }
            if ($bedarr[0] -eq 0 -and $edarr[0] -eq 255){
                $bedarr[0] = 255
                $endcatch = $true
                for ($i = $fbase; $i -gt 0; $i--){
                    if (('8,16,24').split(',') -contains $factor -and $edarr[($i-1)] -eq 255){
                        $bedarr[($i -1)] = 255
                        }
                    elseif ($edarr[$i] -eq 255){
                        $bedarr[$i] = 255
                        }
                    }
                }
            $fend = [ipaddress] $bedarr
            }
        if (!$validend){
            $bedarr = $edarr.Clone()
            for ($i =3; $i -ge $fbase; $i--){
                if ($i -ne $fbase){
                    $bedarr[$i] = 0
                    }
                Else{
                    if ($edarr[$i] -eq 255 -and $bedarr[$i] -eq 255){
                        if ($fplus -ne 255){
                            $bedarr[$i] = 256 - $fplus
                            }
                        Else{
                            $bedarr[$i] = 0
                            }
                        }
                Elseif ($bedarr[$i] -ne 255){
                        if ($bedarr[$i] -le $fplus){
                            $bedarr[$i] = 0
                            }
                    Elseif ($fplus -eq 2){
                            if ($bedarr[$i] -eq $edarr[$i]){
                                if (($bedarr[$i] - 2) -gt 0){
                                    if ($bedarr[$i]%2 -ne 0){
                                        $bedarr[$i]--
                                        }
                                    Else{
                                        $bedarr[$i] = $bedarr[$i] - 2
                                        }
                                    }
                                Else{
                                    $bedarr[$i] = 0
                                    }
                                }
                            }
                    Elseif ($bedarr[$i] -gt $fplus){
                            $tplus = $fplus
                            while (($tplus-1) -lt $bedarr[$i]){
                                $lastb = $tplus
                                $tplus = $tplus + $fplus
                                }
                            $bedarr[$i] = $lastb
                            }
                        }
                    }
                }
            $fend = [ipaddress] $bedarr
            }
        }
    Else{
        $Minblock = $true
        }
    }
Process{
    if ($Minblock){
        Get-PPCIDRMin -Start $starr -End $edarr -base $rbase
        }
    Else{
        if (!$validstart){
            Get-PPCIDRMin -Start $starr -End $fstart -base $fbase
            $starr = $fstart
            for ($i = 3; $i -ge $fbase; $i--){
                if ($i -ne $fbase){
                    $starr[$i] = 0
                    }
                Else{
                    if ($starr[$i] -lt 255){
                        $starr[$i]++
                        }
                    Else{
                        $starr[$i] = 0
                        if ($starr[($i-1)] -lt 255){
                            $starr[($i-1)]++
                            }
                        Else{
                            $starr[($i-1)] = 0
                            if ($starr[($i-2)] -lt 255){
                                $starr[($i-2)]++
                                }
                            Else{
                                $starr[($i-2)]=0
                                if ($starr[($i-3)] -lt 255){
                                    $starr[($i-3)]++
                                    }
                                }
                            }
                        }
                    }
                }
            if ($starr[$fbase]%2 -ne 0){
                $starr[$fbase]--
                }
            }
        while ([ipaddress] $starr -ne $fend){
            $cidque.Enqueue([string][ipaddress] $starr + "/$factor")
            if ($fplus -ne 255){
                if (($starr[$fbase] + $fplus) -lt 255){
                    $starr[$fbase] = $starr[$fbase] + $fplus
                    }
                Elseif ($edarr[0] -eq 255 -and $fbase -eq 0){
                    $starr[0] = 255
                    }
                Elseif ($starr[0] -eq 255 -and $fbase -gt 0){
                    if ($starr[($fbase -1)] -lt 255){
                        $starr[($fbase -1)]++
                        $starr[($fbase)] = 0
                        }
                    Else{
                        if ($fbase -eq 3){
                            if ($starr[1] -lt 255){
                                $starr[1]++
                                $starr[2] = 0
                                $starr[3] = 0
                                }
                            Else{
                                $starr[3] = 255
                                }
                            }
                        Else{
                            $starr[$fbase] = 255
                            }
                        }
                    }
                Else{
                    $starr[$fbase] = 0
                    if ($starr[($fbase-1)] -lt 255){
                        $starr[($fbase-1)]++
                        }
                    Else{
                        $starr[($fbase-1)] = 0
                        if ($starr[($fbase-2)] -lt 255){
                            $starr[($fbase-2)]++
                            }
                        Else{
                            $starr[($fbase-2)] = 0
                            if ($starr[($fbase-3)] -lt 255){
                                $starr[($fbase-3)]++
                                }
                            }
                        }
                    }
                }
            Else{
                $starr[$fbase] = 0
                if ($starr[($fbase-1)] -lt 255){
                    $starr[($fbase-1)]++
                    }
                Else{
                    $starr[($fbase-1)] = 0
                    if ($starr[($fbase-2)] -lt 255){
                        $starr[($fbase-2)]++
                        }
                    Else{
                        $starr[($fbase-2)] = 0
                        if ($starr[($fbase-3)] -lt 255){
                            $starr[($fbase-3)]++
                            }
                        }
                    }
                }
            }
        if (!$validend){
            $estart = $fend.GetAddressBytes()
            Get-PPCIDRMin -Start $estart -End $edarr -base $fbase
            }
        elseif ($endcatch){
            if (('8,16,24').split(',') -contains $factor){
                $cidque.Enqueue([string][ipaddress] $fend + "/$factor")
                }
            }
        }
    }
End{
    if ($cidque.Count -gt 1){
        $null = $cidlist.AddRange($cidque)
        }
    Else{
        $null = $cidlist.Add($cidque.Dequeue())
        }
    if (!$full -and !$Minblock){
        $cidlist.Where({$_ -match ("/$factor")})
        }
    Else{
        $cidlist
        }
    $cidque.Clear()
    $cidlist = $null; $cidque = $null
    [System.GC]::Collect()
    }
}