RSS

Генератор произносимых паролей на PowerShell

22 Мар

Ничего сверх особенного, просто еще один генератор паролей. Вот только это генератор произносимых паролей на PowerShell. Мне надоели полностью рандомные пароли, которые невозможно запомнить. В онлайне я пользовался ресурсом https://genpas.peter23.com, но когда надо создать пользователя в домене, да еще и автоматизировать это дело, скрипт в онлайн не сбегает.

Автор сайта утверждает, что использует алгоритм PWGEN и я не вижу причин ему не верить. Поэтому я собрался в кучку и слямзил оттуда js-скрипт и переточил его под PowerShell. Работает, кстати, начиная с 3 версии точно — формулировки, которые понимает исключительно свежий PS я использовать не стал.

$pwgen_CONSONANT = 1
$pwgen_VOWEL = (1 -shl 1)
$pwgen_DIPTHONG = (1 -shl 2)
$pwgen_NOT_FIRST = (1 -shl 3)

$genpas_spec_symbols = '!"#$%&\()*+,-./:;<=>?@[\]^_`{|}~'''

$pwgen_ELEMENTS = @(
    @("a" , ($pwgen_VOWEL))
    @("ae", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("ah", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("ai", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("b" , ($pwgen_CONSONANT)),
    @("c" , ($pwgen_CONSONANT)),
    @("ch", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG)),
    @("d" , ($pwgen_CONSONANT)),
    @("e" , ($pwgen_VOWEL)),
    @("ee", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("ei", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("f" , ($pwgen_CONSONANT)),
    @("g" , ($pwgen_CONSONANT)),
    @("gh", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG -bor $pwgen_NOT_FIRST)),
    @("h" , ($pwgen_CONSONANT)),
    @("i" , ($pwgen_VOWEL)),
    @("ie", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("j" , ($pwgen_CONSONANT)),
    @("k" , ($pwgen_CONSONANT)),
    @("l" , ($pwgen_CONSONANT)),
    @("m" , ($pwgen_CONSONANT)),
    @("n" , ($pwgen_CONSONANT)),
    @("ng", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG -bor $pwgen_NOT_FIRST)),
    @("o" , ($pwgen_VOWEL)),
    @("oh", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("oo", ($pwgen_VOWEL -bor $pwgen_DIPTHONG)),
    @("p" , ($pwgen_CONSONANT)),
    @("ph", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG)),
    @("qu", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG)),
    @("r" , ($pwgen_CONSONANT)),
    @("s" , ($pwgen_CONSONANT)),
    @("sh", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG)),
    @("t" , ($pwgen_CONSONANT)),
    @("th", ($pwgen_CONSONANT -bor $pwgen_DIPTHONG)),
    @("u" , ($pwgen_VOWEL)),
    @("v" , ($pwgen_CONSONANT)),
    @("w" , ($pwgen_CONSONANT)),
    @("x" , ($pwgen_CONSONANT)),
    @("y" , ($pwgen_CONSONANT)),
    @("z" , ($pwgen_CONSONAN))
)

function pwgen_generate ($pwlen, $inc_capital, $inc_number, $inc_spec) {
    $result = ""
    while (-not $result) {
        $result = pwgen_generate0 -pwlen $pwlen -inc_capital $inc_capital -inc_number $inc_number -inc_spec $inc_spec
    }
    return $result
}

function pwgen_generate0 ([int]$pwlen, [bool]$inc_capital, [bool]$inc_number, [bool]$inc_spec) {
    $result = ""
    $prev = 0;
    $isFirst = $true;
    if ((Get-Random -Maximum 1.0) -lt 0.5) {
        $shouldBe = $pwgen_VOWEL
    }
    else {
        $shouldBe = $pwgen_CONSONANT
    }
    while ($result.length -lt $pwlen) {
        $i = [math]::Truncate(($pwgen_ELEMENTS.count - 1) * (Get-Random -Maximum 1.0))
        $str = $pwgen_ELEMENTS[$i][0]
        $flags = $pwgen_ELEMENTS[$i][1]
        if (($flags -band $shouldBe) -eq 0) {
            continue
        }
        if ($isFirst -and ($flags -band $pwgen_NOT_FIRST)) {
            continue
        }
        if (($prev -band $pwgen_VOWEL) -and ($flags -band $pwgen_VOWEL) -and ($flags -band $pwgen_DIPTHONG)) {
            continue
        }
        if (($result.length + $str.length) -gt $pwlen) {
            continue
        }
        if ($inc_capital) {
            if (($isFirst -or ($flags -band $pwgen_CONSONANT)) -and ((Get-Random -Maximum 1.0) -gt 0.3)) {
                $str = $str.substring(0, 1).toupper() + $str.substring(1)
                $inc_capital = $false
            }
        }
        $result += $str
        if ($inc_number) {
            if ((-not $isFirst) -and ((Get-Random -Maximum 1.0) -lt 0.3)) {
                if (($result.length + $str.length) -gt $pwlen) {
                    $result = $result.Substring(0, $result.Length - 1)
                }
                $result += [math]::Truncate(10 * (Get-Random -Maximum 1.0)).toString()
                $inc_number = $false
                $isFirst = $true
                $prev = 0
                if ((Get-Random -Maximum 1.0) -lt 0.5) {
                    $shouldBe = $pwgen_VOWEL
                }
                else {
                    $shouldBe = $pwgen_CONSONANT
                }
                continue
            }
        }

        if ($inc_spec) {
            if ((-not $isFirst) -and ((Get-Random -Maximum 1.0) -lt 0.3)) {
                if (($result.length + $str.length) -gt $pwlen) {
                    $result = $result.Substring(0, $result.Length - 1)
                }
                $possible = $genpas_spec_symbols
                $result += $possible.chars([math]::Truncate((Get-Random -Maximum 1.0) * $possible.length))
                $inc_spec = $false
                $isFirst = $true
                $prev = 0
                if ((Get-Random -Maximum 1.0) -lt 0.5) {
                    $shouldBe = $pwgen_VOWEL
                }
                else {
                    $shouldBe = $pwgen_CONSONANT
                }
                continue
            }
        }
        if ($shouldBe -eq $pwgen_CONSONANT) {
            $shouldBe = $pwgen_VOWEL;
        }
        else {
            if (($prev -band $pwgen_VOWEL) -or ($flags -band $pwgen_DIPTHONG) -or ((Get-Random -Maximum 1.0) -gt 0.3)) {
                $shouldBe = $pwgen_CONSONANT;
            }
            else {
                $shouldBe = $pwgen_VOWEL;
            }
        }
        $prev = $flags;
        $isFirst = $false;
    }
    if ($inc_capital -or $inc_number -or $inc_spec) {
        return $null
    }
    return $result
}

Использовать в формате:

pwgen_generate -pwlen 10 -inc_capital $true -inc_number $true -inc_spec $false
  • pwlen — длина пароля, число
  • inc_capital — нужны ли заглавные буквы, булево
  • inc_number — нужны ли цифры, булево
  • inc_spec — нужны ли спецсимволы, булево

Короче автору сайта — респект, мне — просто спасибо.

 
 

Метки: , , ,

Оставьте комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.