Determine the third octet of an IP address based on user entered site number I am trying to create a function for a larger script to determine the third octet of a site IP address based off a user entered site number. I have actually come up with the function, but was hoping that someone could help me come up with something that is simpler and more elegant, instead of the multitude of nested if statements that I came up with. Here are the rules:


For sites numbered 0001 - 0255, the third octet is the last 3 digits of the site number, less any zeroes preceding a real number (e.g. Site 0007 = 10.10.7.xxx)
For sites numbered 0256 - 0399 and 0500 - 1999 (except 1202), the third octet is the last 2 digits of the site number less any zeroes preceding a real number (e.g. site 0315 = 10.22.15.xxx)
For sites numbered 401 - 499, the third octet is the last two digits of the site number +100 (e.g. 0401 = 10.20.101.xxx)
Site 1202 is an exception to the above rule, where the third octet is the last 3 digits (.202)
For sites 5000 and above (5000 - 9999), the first digit is dropped, and then the rules above are followed. (e.g. 8248 = 10.12.48.xxx)


Here is what I have come up with. It is not very elegant, but it seems to work. Note that the first three lines will be in another function in the script, but are here for testing purposes.

$global:site = Read-Host 'What is the 4 digit site number?' #must include leading zeros
[int]$global:sitecheck=$site #need for comparasion operators
[string]$global:sitestring=$site

if ($sitecheck -le 255)
    {
    if ($sitestring.substring(0,3) -eq '000') #(i.e. 0001 - 0009)
        {
        $global:thirdoct = $sitestring.substring(3,1) #(i.e. 1-9)
        }
        elseif ($sitestring.substring(0,2) -eq '00') #(i.e. 0010 - 0099) 
            {
            $global:thirdoct = $sitestring.substring(2,2) #(i.e. 10 - 99)
            }
            elseif ($sitestring.substring(0,1) -eq '0') #(i.e. 0100 - 0255)
            {
            $global:thirdoct = $sitestring.substring(1,3) #(i.e. 100 - 255)
            }
}           
elseif ($sitecheck -ge 256 -and $sitecheck -le 399 ) 
    {
    if ($sitestring.substring(2,1) -eq '0') 
        {
        $global:thirdoct = $sitestring.substring(3,1)
        }
        else
        {
        $global:thirdoct = $sitestring.substring(2,2)
        }
}
elseif ($sitecheck -ge 401 -and $sitecheck -le 499) 
    {
    $global:thirdoct = 100+$sitestring.substring(2,2)
    }
elseif ($sitecheck -ge 501 -and $sitecheck -le 799) 
    {
    if ($sitestring.substring(2,1) -eq '0')
        {
        $global:thirdoct = $sitestring.substring(3,1)
        }
        else
        {
        $global:thirdoct = $sitestring.substring(2,2)
        }
    }
elseif ($sitecheck -eq 1202)
    {
    $global:thirdoct = $sitestring.substring(1,3)
    }
elseif ($sitecheck -ge 5000 -and $sitecheck -le 9999) 
    {
    $site5000 = [int]$sitestring.substring(1,3)
    if ($site5000 -le 255)
       {
       if ($sitestring.substring(1,2) -eq '00')
           {
           $global:thirdoct = $sitestring.substring(3,1)
           }
                elseif ($sitestring.substring(1,1) -eq '0')
                {
                $global:thirdoct = $sitestring.substring(2,2)
                }
                    else 
                    {
                    $global:thirdoct = $sitestring.substring(1,3)
                    }
    }
    elseif (($site5000 -ge 256 -and $site5000 -le 399) -or ($site5000 -ge 501 -and $site5000 -le 999))
        {
        $global:thirdoct = $sitestring.substring(2,2)
        }
    elseif ($site5000 -ge 401 -and $site5000 -le 499)
        {
        $global:thirdoct = 100+$sitestring.substring(2,2)
        }
    }
Let's start with a table of inputs and outputs, because it may not be exactly the same as what you expect from your script.  The first column is the input range, the other column is the transformation applied for those inputs.

0000-0255       self
0256-0399       last2
0400            undefined
0401-0499       -300
0500            undefined
0501-0799       last2
0800-1201       undefined
1202            last3
1203-4999       undefined
5000-5255       last3
5256-5399       last2
5400-5500       undefined
5501-5999       last2
6000+           same as 5000-5999


The best way to manage these cases is with a data structure.  A switch statement can work too but there's going to be a lot of repetition, and you really want something that lets you focus on the data.  

In this version, the ranges are an array of arrays.  Each inner array is a lower bound, an upper bound, and a script block that transforms input to output.  As a special case, a negative result from the script block means "restart the conversion with this new value (after making it positive)"—this lets us reuse the low patterns for most of 5000-5999, and then reuse the 5000-5999 pattern for 6000-9999.

We simply traverse the array looking matches, and apply the transforms from matching rows. (There's only ever one matching row per call to convert, in this example, but the code allows overlapping ranges; matching transforms will apply in order).

$ranges = @(
    @(    0,  255, { $_ }                  ),
    @(  256,  399, { $_ % 100 }            ),
    @(  401,  499, { $_ - 300 }            ),
    @(  501,  799, { $_ % 100 }            ),
    @( 1202, 1202, { $_ % 1000 }           ),
    @( 5000, 5399, { -($_ % 1000) }        ), # redo using last 3 digits
    @( 5501, 5999, { -($_ % 1000) }        ),
    @( 6000, 9999, { -($_ % 1000 + 5000) } )  # redo using 5000 + last 3
)

$convert = {
    $_ = [int]$args[0]
    $out = -1
    foreach ($range in $ranges) {
        if ($_ -ge $range[0] -and $_ -le $range[1]) { 
            $out = &amp; $range[2] 
            # negative result means re-do the conversion with a new value
            if ($out -lt 0) { $out = &amp; $convert ($out * -1) }
        }
    }
    return $out
}

$site = Read-Host 'enter the site code: '
$octet = &amp; $convert $site
if ($octet -ge 0) {
    echo $octet
} else {
    echo "error - $site has no defined octet"
}