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