69 lines
2.1 KiB
PHP
69 lines
2.1 KiB
PHP
|
<?php
|
||
|
namespace nur\passwd;
|
||
|
|
||
|
abstract class AbstractGenerator {
|
||
|
const NB_BLOCKS = 4;
|
||
|
const NB_PUNCTS = 2;
|
||
|
|
||
|
const CONSONNES = "bcdfghjklmnpqrstvwxz";
|
||
|
const VOYELLES = "aeiuoy";
|
||
|
const PUNCTS = "+-*/=!@?:#";
|
||
|
const MAPPINGS = [
|
||
|
# éviter certaines combinaisons potentiellement gênantes
|
||
|
"sexe" => "xese",
|
||
|
"sexy" => "xyse",
|
||
|
"suce" => "cesu",
|
||
|
"bite" => "tebi",
|
||
|
"cabo" => "boca",
|
||
|
"pipe" => "pepi",
|
||
|
"cocu" => "cuco",
|
||
|
"pute" => "tepu",
|
||
|
];
|
||
|
|
||
|
function __construct(?int $nbBlocks=null, ?int $nbPuncts=null) {
|
||
|
if ($nbBlocks === null) $nbBlocks = static::NB_BLOCKS;
|
||
|
if ($nbPuncts === null) $nbPuncts = static::NB_PUNCTS;
|
||
|
if ($nbBlocks < 1) $nbBlocks = 1;
|
||
|
if ($nbPuncts > $nbBlocks) $nbPuncts = $nbBlocks;
|
||
|
$this->nbBlocks = $nbBlocks;
|
||
|
$this->nbPuncts = $nbPuncts;
|
||
|
}
|
||
|
|
||
|
/** @var int */
|
||
|
protected $nbBlocks, $nbPuncts;
|
||
|
|
||
|
function generate(?int $nbBlocks=null, ?int $nbPuncts=null, ?int $seed=null): string {
|
||
|
if ($nbBlocks === null) $nbBlocks = $this->nbBlocks;
|
||
|
if ($nbPuncts === null) $nbPuncts = $this->nbPuncts;
|
||
|
if ($seed !== null) mt_srand($seed);
|
||
|
$maxc = strlen(self::CONSONNES) - 1;
|
||
|
$maxv = strlen(self::VOYELLES) - 1;
|
||
|
$maxp = strlen(self::PUNCTS) - 1;
|
||
|
$size = $nbBlocks * 2;
|
||
|
$sindex = 0;
|
||
|
$syllabes = [];
|
||
|
while ($sindex < $size) {
|
||
|
$lindex = count($syllabes) - 1;
|
||
|
do {
|
||
|
$consonne = self::CONSONNES[mt_rand(0, $maxc)];
|
||
|
$voyelle = self::VOYELLES[mt_rand(0, $maxv)];
|
||
|
$syllabe = $consonne.$voyelle;
|
||
|
# pas deux fois la même syllabe de suite
|
||
|
$repetition = ($lindex >= 0 && $syllabes[$lindex] == $syllabe)
|
||
|
|| ($lindex >= 1 && $syllabes[$lindex - 1] == $syllabe);
|
||
|
} while ($repetition);
|
||
|
$syllabes[] = $syllabe;
|
||
|
$sindex++;
|
||
|
if ($nbPuncts > 0 && $sindex % 2 == 0 && mt_rand() % 2 == 0) {
|
||
|
$syllabes[] = self::PUNCTS[mt_rand(0, $maxp)];
|
||
|
$nbPuncts--;
|
||
|
}
|
||
|
}
|
||
|
$password = implode("", $syllabes);
|
||
|
foreach (self::MAPPINGS as $from => $to) {
|
||
|
$password = str_replace($from, $to, $password);
|
||
|
}
|
||
|
return $password;
|
||
|
}
|
||
|
}
|