initialization
This commit is contained in:
commit
9ff09693ed
92 files changed
+46209
No files matched your search
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Generators;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* High Entropy Password Generator
|
||||
*
|
||||
* Generates cryptographically secure random passwords with customizable
|
||||
* character sets based on user preferences.
|
||||
*/
|
||||
class HighEntropyGenerator extends AbstractPasswordGenerator
|
||||
{
|
||||
private const GENERATOR_ID = 'high_entropy';
|
||||
|
||||
private const LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';
|
||||
private const UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
private const NUMBERS = '0123456789';
|
||||
private const SYMBOLS = '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
||||
|
||||
public function __construct(?LoggerInterface $logger = null)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return self::GENERATOR_ID;
|
||||
}
|
||||
|
||||
public function getVersion(): string
|
||||
{
|
||||
return '1.1.0';
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'High Entropy';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Cryptographically secure random passwords with customizable character sets';
|
||||
}
|
||||
|
||||
/**
|
||||
* Centralized option definitions
|
||||
*/
|
||||
public function getOptionDefinitions(): array
|
||||
{
|
||||
$options = [
|
||||
'length' => [
|
||||
'type' => 'integer',
|
||||
'default' => 16,
|
||||
'min' => 8,
|
||||
'max' => 128,
|
||||
'required' => false,
|
||||
'group' => 'basic',
|
||||
'description' => 'Total length of the generated password'
|
||||
],
|
||||
'include_uppercase' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
'required' => false,
|
||||
'group' => 'character_set',
|
||||
'description' => 'Include uppercase letters (A-Z)'
|
||||
],
|
||||
'include_lowercase' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
'required' => false,
|
||||
'group' => 'character_set',
|
||||
'description' => 'Include lowercase letters (a-z)'
|
||||
],
|
||||
'include_numbers' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
'required' => false,
|
||||
'group' => 'character_set',
|
||||
'description' => 'Include numbers (0-9)'
|
||||
],
|
||||
'include_symbols' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
'required' => false,
|
||||
'group' => 'character_set',
|
||||
'description' => 'Include symbols (e.g., !@#$%)'
|
||||
],
|
||||
];
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function generate(int $count = 1, array $options = []): array
|
||||
{
|
||||
$options = array_merge($this->getDefaultOptions(), $options);
|
||||
$passwords = [];
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$passwords[] = $this->generateSingle($options);
|
||||
}
|
||||
|
||||
return $passwords;
|
||||
}
|
||||
|
||||
private function generateSingle(array $options): string
|
||||
{
|
||||
$characterSet = $this->buildCharacterSet($options);
|
||||
$length = $options['length'];
|
||||
|
||||
if (empty($characterSet)) {
|
||||
throw new \RuntimeException('No character types selected');
|
||||
}
|
||||
|
||||
// Generate password ensuring at least one character from each selected type
|
||||
$password = $this->generateWithGuaranteedTypes($characterSet, $length, $options);
|
||||
|
||||
// Shuffle the password to randomize position of guaranteed characters
|
||||
return $this->shuffleString($password);
|
||||
}
|
||||
|
||||
private function buildCharacterSet(array $options): string
|
||||
{
|
||||
$characterSet = '';
|
||||
|
||||
if ($options['include_lowercase'] ?? false) {
|
||||
$characterSet .= self::LOWERCASE;
|
||||
}
|
||||
|
||||
if ($options['include_uppercase'] ?? false) {
|
||||
$characterSet .= self::UPPERCASE;
|
||||
}
|
||||
|
||||
if ($options['include_numbers'] ?? false) {
|
||||
$characterSet .= self::NUMBERS;
|
||||
}
|
||||
|
||||
if ($options['include_symbols'] ?? false) {
|
||||
$characterSet .= self::SYMBOLS;
|
||||
}
|
||||
|
||||
return $characterSet;
|
||||
}
|
||||
|
||||
private function generateWithGuaranteedTypes(string $characterSet, int $length, array $options): string
|
||||
{
|
||||
$password = '';
|
||||
$guaranteedChars = [];
|
||||
|
||||
// Add at least one character from each selected type
|
||||
if ($options['include_lowercase'] ?? false) {
|
||||
$guaranteedChars[] = self::LOWERCASE[random_int(0, strlen(self::LOWERCASE) - 1)];
|
||||
}
|
||||
|
||||
if ($options['include_uppercase'] ?? false) {
|
||||
$guaranteedChars[] = self::UPPERCASE[random_int(0, strlen(self::UPPERCASE) - 1)];
|
||||
}
|
||||
|
||||
if ($options['include_numbers'] ?? false) {
|
||||
$guaranteedChars[] = self::NUMBERS[random_int(0, strlen(self::NUMBERS) - 1)];
|
||||
}
|
||||
|
||||
if ($options['include_symbols'] ?? false) {
|
||||
$guaranteedChars[] = self::SYMBOLS[random_int(0, strlen(self::SYMBOLS) - 1)];
|
||||
}
|
||||
|
||||
// Add guaranteed characters
|
||||
$password = implode('', $guaranteedChars);
|
||||
|
||||
// Fill remaining length with random characters from full set
|
||||
$remainingLength = $length - count($guaranteedChars);
|
||||
for ($i = 0; $i < $remainingLength; $i++) {
|
||||
$password .= $characterSet[random_int(0, strlen($characterSet) - 1)];
|
||||
}
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
private function shuffleString(string $string): string
|
||||
{
|
||||
$characters = str_split($string);
|
||||
|
||||
// Fisher-Yates shuffle using cryptographically secure random
|
||||
for ($i = count($characters) - 1; $i > 0; $i--) {
|
||||
$j = random_int(0, $i);
|
||||
[$characters[$i], $characters[$j]] = [$characters[$j], $characters[$i]];
|
||||
}
|
||||
|
||||
return implode('', $characters);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user