Invoke-SymbolEnumeration.ps1


<#PSScriptInfo
 
.VERSION 1.0.0
 
.GUID 04eb65fa-5baa-4074-9112-a61c20c45a14
 
.AUTHOR andy_mishechkin@hotmail.com
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
 This script was created only for research and teaching goals and may be useful in realization of various symbols generators
 This version of script can use only digits and latin symbols for building the combinations (planed to add cyrilic and special symbols).
 You can extract functions from this script for using in separate module.
#>
 

Param()

function Get-Enumerator 
{
    param(
        [Parameter(Mandatory)] [int] $index
    )

    if ($index -eq 0)
    {
        {
            $global:Symbols | ForEach-Object { 
                $global:CharArray[0] = $_ 
                $SymString = Get-SymString
                Write-Debug $SymString   
            }
        }
    }
    else
    {
        {
            $PrEnum = ('$global:Enums[' + [string]($index-1) + ']')
            $global:Symbols | ForEach-Object { 
                $global:CharArray[$index] = $_
                Invoke-Expression "& $PrEnum"
            }
        }.GetNewClosure()
    }
}

function Get-SymString
{
    $SrcString = -join $global:CharArray
    $RevArray = $SrcString.ToCharArray()
    [array]::Reverse($RevArray)
    return (-join $RevArray)
}

function New-Enumerator
{
    param(
        [Parameter(Mandatory)] [int] $ArrLength,
        [switch]$Digits,
        [switch]$LatinUpper,
        [switch]$LatinLower
    )

    $global:Symbols = New-Object System.Collections.ArrayList
    $Codes = @()
    if ($Digits) { $Codes += (48..57) }
    if ($LatinUpper) { $Codes += (65..90) }
    if ($LatinLower) { $Codes += (97..122) }
    
    $Codes | ForEach-Object { $global:Symbols.Add([char]$_) > $null }

    $global:CharArray = New-Object -TypeName 'Char[]' -ArgumentList $ArrLength 
    $global:Enums = New-Object -TypeName 'object[]' -ArgumentList $ArrLength
    for ($index=0; $index -lt $ArrLength; $index++)
    {
        $global:Enums[$index] = Get-Enumerator -index $index
    }
} 

function Invoke-Enumeration
{
    param(
        [Parameter(Mandatory)] [int] $ArrLength,
        [switch]$Digits,
        [switch]$LatinUpper,
        [switch]$LatinLower
    )
    
    $NewEnumeratorArgs = @{ ArrLength = $ArrLength }
    if ($Digits) { $NewEnumeratorArgs.Add("Digits", $true) }
    if ($LatinUpper) { $NewEnumeratorArgs.Add("LatinUpper", $true) }
    if ($LatinLower) { $NewEnumeratorArgs.Add("LatinLower", $true) }

    New-Enumerator @NewEnumeratorArgs

    for($index=0; $index -lt $global:Enums.Length; $index++)
    {
        & $global:Enums[$index]
    }
}

$DebugPreference = "Continue"
#$DebugPreference = "SilentlyContinue"

Invoke-Enumeration -ArrLength 3 -Digits -LatinUpper
Invoke-Enumeration -ArrLength 4 -Digits
Invoke-Enumeration -ArrLength 3 -Digits -LatinLower
Invoke-Enumeration -ArrLength 3 -Digits -LatinUpper -LatinLower