<?php

final class PasswordConfig
{
    public const MIN_LENGTH = 8;
    public const MAX_LENGTH = 128;

    // Removidos: O, 0, I, l, 1
    public const LOWERCASE = 'abcdefghijkmnopqrstuvwxyz';
    public const UPPERCASE = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
    public const NUMBERS   = '23456789';

    public const SYMBOLS = '!@#$%&*-_+=?';
}

final class PasswordGenerator
{
    public function generate(
        int $length,
        bool $useUppercase = true,
        bool $useNumbers = true,
        bool $useSymbols = true
    ): string {

        if ($length < PasswordConfig::MIN_LENGTH || $length > PasswordConfig::MAX_LENGTH)
        {
            throw new InvalidArgumentException(
                sprintf(
                    'O tamanho da senha deve estar entre %d e %d caracteres.',
                    PasswordConfig::MIN_LENGTH,
                    PasswordConfig::MAX_LENGTH
                )
            );
        }

        $characterGroups[] = PasswordConfig::LOWERCASE;

        if ($useUppercase) {$characterGroups[] = PasswordConfig::UPPERCASE;}

        if ($useNumbers) {$characterGroups[] = PasswordConfig::NUMBERS;}

        if ($useSymbols) {$characterGroups[] = PasswordConfig::SYMBOLS;}

        if ($length < count($characterGroups)) {
            throw new InvalidArgumentException(
                'O tamanho da senha é insuficiente para atender aos requisitos mínimos.'
            );
        }

        $passwordCharacters = [];

        /**
         * Garante pelo menos um caractere de cada categoria.
         * contem 4 categorias possiveis
         */
        foreach ($characterGroups as $group) {
            $passwordCharacters[] = $this->randomCharacter($group);
        }

        /**
         * Conjunto total para completar a senha.
         * Junta todos os grupos de string do array
         * formando uma unica string
         */
        $availableCharacters = implode('', $characterGroups);

        /**
        * 
        */
        while (count($passwordCharacters) < $length) {
            $passwordCharacters[] = $this->randomCharacter(
                $availableCharacters
            );
        }
        /**
        *embaralha os indices do array de caracteres definidos aleatoriamente
        */
        shuffle($passwordCharacters);

        return implode('', $passwordCharacters);
    }

    private function randomCharacter(string $characters): string
    {
        $index = random_int(0,strlen($characters) - 1);

        return $characters[$index];
    }
}

function readLength(): int
{
    echo 'Tamanho da senha: ';

    $input = trim((string) fgets(STDIN));

    if (!ctype_digit($input)) {
        throw new InvalidArgumentException(
            'Informe apenas números inteiros positivos.'
        );
    }

    return (int) $input;
}


function writeOutput(string $message): void
{
    echo $message . PHP_EOL;
}

try {

    $length = readLength();

    $generator = new PasswordGenerator();

    $password = $generator->generate(
        length: $length,
        useUppercase: true,
        useNumbers: true,
        useSymbols: true
    );

    writeOutput("Senha gerada: {$password}");

} catch (Throwable $exception) {

    writeOutput(
        'Erro: ' . $exception->getMessage()
    );
}

// $LOWERCASE = 'abcdefghijkmnopqrstuvwxyz';
// $UPPERCASE = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
// $NUMBERS   = '23456789';

// $SYMBOLS = '!@#$%&*-_+=?';


// $characterGroups=[$LOWERCASE,$UPPERCASE,$NUMBERS,$SYMBOLS];

// $passwordCharacters = [];

// function randomCharacter(string $characters): string
// {
//     $index = random_int(0,strlen($characters) - 1);

//     return $characters[$index];
// }

// foreach ($characterGroups as $group) {
//     $passwordCharacters[] = randomCharacter($group);
// }

// var_dump($passwordCharacters);













Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: