Get-Subnet, a PowerShell advanced function

I wrote a PowerShell advanced function “Get-Subnet” to return a subnet mask for a given bit or bit range.

The cmdlet, with embedded help, including examples:

<#
.Synopsis
   Returns a subnet mask for a given bit or bit range.
.DESCRIPTION
   For a given number of bits, or range of bits, returns the equivilant subnet mask(s) and number of available hosts in that subnet.
   Returns NetworkBits, SubnetMask, NumberOfHosts for each bit.
   NetworkBits is provided for completeness, in the case of multiple objects returned. 
   SubnetMask string is useful for situations where you know network bits and want to set a subnet mask on a network card. 
   NumberOfHosts is useful for understanding implications of using a selected number of bits.
.EXAMPLE
   PS C:\>Get-Subnet

Returns:
>   NetworkBits SubnetMask      NumberOfHosts
>   ----------- ----------      -------------
>             8 255.0.0.0            16777214
>             9 255.128.0.0           8388606
>            10 255.192.0.0           4194302
>            11 255.224.0.0           2097150
>            12 255.240.0.0           1048574
>            13 255.248.0.0            524286
>            14 255.252.0.0            262142
>            15 255.254.0.0            131070
>            16 255.255.0.0             65534
>            17 255.255.128.0           32766
>            18 255.255.192.0           16382
>            19 255.255.224.0            8190
>            20 255.255.240.0            4094
>            21 255.255.248.0            2046
>            22 255.255.252.0            1022
>            23 255.255.254.0             510
>            24 255.255.255.0             254
>            25 255.255.255.128           126
>            26 255.255.255.192            62
>            27 255.255.255.224            30
>            28 255.255.255.240            14
>            29 255.255.255.248             6
>            30 255.255.255.252             2

   With no parameters, the command lists subnet masks for bit range 8 to 30.
.EXAMPLE
   PS C:\>Get-Subnet -MinBits 20 -MaxBits 24

Returns:
>   NetworkBits SubnetMask    NumberOfHosts
>   ----------- ----------    -------------
>            20 255.255.240.0          4094
>            21 255.255.248.0          2046
>            22 255.255.252.0          1022
>            23 255.255.254.0           510
>            24 255.255.255.0           254
   
   Return a specific range of subnet masks.
.EXAMPLE
   PS C:\>$a = (Get-Subnet -Bits 20).SubnetMask
   PS C:\>Write-Host "20 bit Subnet mask is $a"

   Returns:
>  20 bit Subnet mask is 255.255.240.0

   Store a specific subnet mask to a variable.
#>

function Get-Subnet

{
              [CmdletBinding(DefaultParameterSetName='Parameter Set 1')]
              Param
              (
                [Parameter(ParameterSetName='Parameter Set 1')]
                $Bits,
          
                [Parameter(ParameterSetName='Parameter Set 2')]
                $MinBits,

                [Parameter(ParameterSetName='Parameter Set 2')]
                $MaxBits

              )
    if ($Bits -ne $null) {
        $MinBits = $Bits
        $MaxBits = $Bits
        }
        else {
            if ($MinBits -eq $null) {
                $MinBits = 8
                }
            if ($MaxBits -eq $null) {
                $MaxBits = 30
                }
            }

    foreach ($i in ($MinBits..$MaxBits)) 
    {
        $binary = ([string]"1" * $i).PadRight(32,"0")

        $InvertedBinary = ([string]"0" * $i).PadRight(32,"1")

        $NumberOfHosts = [convert]::ToInt32($InvertedBinary,2) -1 

        $Oct1 = [string][convert]::ToInt32($binary.Substring(0,8),2)
        $Oct2 = [string][convert]::ToInt32($binary.Substring(8,8),2)
        $Oct3 = [string][convert]::ToInt32($binary.Substring(16,8),2)
        $Oct4 = [string][convert]::ToInt32($binary.Substring(24,8),2)

        $SubnetMask = $Oct1 + "." + $Oct2 + "." + $Oct3 + "." + $Oct4

        [PsCustomObject]@{
            "NetworkBits" = $i; 
            "SubnetMask" = $SubnetMask; 
            "NumberOfHosts" = $NumberOfHosts
            }
        } 

}

The XOR Cipher in PowerShell

DISCLAIMER: This is presented for educational purposes only. It is not intended for use as production cryptography. The example here is not secure and is vulnerable to multiple attacks.

Inspired by my son’s recent interest in ciphers, I decided to write a basic XOR cipher in PowerShell. Given your plaintext and key, the script returns the ciphertext.

What does it do?
The plaintext and the key are strings. If the key is shorter then the plaintext, then we repeat the key until it’s as long as the plaintext. A string is made up of bytes. And bytes are made up bits. For each bit in the plaintext, we do an Exclusive Or (XOR) Operation with the coresponding bit in the repeated key. The result is stored in the ciphertext.

What is Exclusive Or? https://en.wikipedia.org/wiki/Exclusive_or

Exclusive Or is an operation that outputs TRUE when the inputs differ.
For example:

Plaintext  01010000
Key        01101011
XOR-----------------
Ciphertext 00111011

A nice feature of XOR is that it is easly reversable. If we XOR the key with the ciphertext, we get the plaintext back.

The code:

function encode($plaintext, $key)
    {
    $cyphertext = ""
    $keyposition = 0
    $KeyArray = $key.ToCharArray()
    $plaintext.ToCharArray() | foreach-object -process {
        $cyphertext += [char]([byte][char]$_ -bxor $KeyArray[$keyposition])
        $keyposition += 1
        if ($keyposition -eq $key.Length) {$keyposition = 0}
        }
    return $cyphertext
    }

PowerShell Hex Functions

I wrote some basic functions to convert a string to hexadecimal, to convert hexadecimal to a string. Also a function to dump a string to it’s component bytes, listing on each line, the character, it’s ASCII code in hexadecimal, and ASCII code in decimal. Example output:

PS C:\> StringToHex "This is an example!@#"
5468697320697320616E206578616D706C65214023
PS C:\> HexToString "4861726B212053686F77206D6520616E206578616D706C653F3F"
Hark! Show me an example??
PS C:\> HexDump "So how is this?"
S 0x53 83
o 0x6F 111
  0x20 32
h 0x68 104
o 0x6F 111
w 0x77 119
  0x20 32
i 0x69 105
s 0x73 115
  0x20 32
t 0x74 116
h 0x68 104
i 0x69 105
s 0x73 115
? 0x3F 63

The code. They are basic functions, not Advanced Functions, so nothing fancy.

function StringToHex($i) {
    $r = ""
    $i.ToCharArray() | foreach-object -process {
        $r += '{0:X}' -f [int][char]$_
        }
    return $r
    }

function HexToString($i) {
    $r = ""
    for ($n = 0; $n -lt $i.Length; $n += 2)
        {$r += [char][int]("0x" + $i.Substring($n,2))}
    return $r
    }

function HexDump($i) {
    $i.ToCharArray() | foreach-object -process {
        $num = [int][char]$_
        $hex = "0x" + ('{0:X}' -f $num)
        "$_ $hex $num"
        }
    }