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;
 | |
|   }
 | |
| }
 |