BattleFaction2019.psm1

function Get-CaesarCipher {
    [CmdletBinding()]
    param (
        [parameter(Mandatory = $true)]
        [string]$Text,
        [parameter(Mandatory = $true)]
        [int]$SecretNumber,
        [string]$RootString =  $([char[]]$(32..126) -join ''),
        [switch]$Encode,
        [switch]$Decode
    )
    
    begin {
        # If you are decoding, you need to reverse the lookup
        if ($Decode) { $SecretNumber = -$SecretNumber }
        # Modulus is used to keep the values inside array of possible positions
        $Modulus = $RootString.length
        Write-Verbose "Modulus: $Modulus"
        If ($SecretNumber -lt 0) {
            $SecretNumber = $Modulus + ($SecretNumber % $Modulus)
        }
        Write-Verbose $SecretNumber
    }
    
    process {
        # Build 2 hashtables. One for looking a letter based on poition in the string and one for looking up the position in the string based on the letter
        $Counter = @{ }
        $Letter = @{ }
        $i = 0
        [int[]][char[]]$RootString | ForEach-Object { $Counter.add($i, $_); $Letter.Add($_, $i); $i++ }

        # Convert original chars to the char ints matching the secret number
        $Converted = [int[]][char[]]$Text | ForEach-Object {
            try {
                if ($_ -eq 10 -or $_ -eq 13) { $_ } else {
                    $no = $letter[$_]
                    $Counter[$($($no + $SecretNumber) % $Modulus)]
                }
            }
            catch {
                Write-Warning "Error on $_"
            }
        }
    }
    
    end {
        # Just joining the string would remove new line carriage return, formatting a string allows them to expand correctly
        $str = ""
        for ($j = 0; $j -le $Converted.count - 1; $j++) { $str += "{$j}" }
        $str -f $($Converted.foreach{ [char]$_ })
    }
}