vendor/ircmaxell/random-lib/lib/RandomLib/Factory.php line 78

Open in your IDE?
  1. <?php
  2. /*
  3.  * The RandomLib library for securely generating random numbers and strings in PHP
  4.  *
  5.  * @author     Anthony Ferrara <ircmaxell@ircmaxell.com>
  6.  * @copyright  2011 The Authors
  7.  * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
  8.  * @version    Build @@version@@
  9.  */
  10. /**
  11.  * The Random Factory
  12.  *
  13.  * Use this factory to instantiate random number generators, sources and mixers.
  14.  *
  15.  * PHP version 5.3
  16.  *
  17.  * @category   PHPPasswordLib
  18.  * @package    Random
  19.  *
  20.  * @author     Anthony Ferrara <ircmaxell@ircmaxell.com>
  21.  * @copyright  2011 The Authors
  22.  * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
  23.  *
  24.  * @version    Build @@version@@
  25.  */
  26. namespace RandomLib;
  27. use SecurityLib\Strength;
  28. /**
  29.  * The Random Factory
  30.  *
  31.  * Use this factory to instantiate random number generators, sources and mixers.
  32.  *
  33.  * @category   PHPPasswordLib
  34.  * @package    Random
  35.  *
  36.  * @author     Anthony Ferrara <ircmaxell@ircmaxell.com>
  37.  */
  38. class Factory extends \SecurityLib\AbstractFactory
  39. {
  40.     /**
  41.      * @var array A list of available random number mixing strategies
  42.      */
  43.     protected $mixers = array();
  44.     /**
  45.      * @var array A list of available random number sources
  46.      */
  47.     protected $sources = array();
  48.     /**
  49.      * Build a new instance of the factory, loading core mixers and sources
  50.      *
  51.      * @return void
  52.      */
  53.     public function __construct()
  54.     {
  55.         $this->loadMixers();
  56.         $this->loadSources();
  57.     }
  58.     /**
  59.      * Get a generator for the requested strength
  60.      *
  61.      * @param Strength $strength The requested strength of the random number
  62.      *
  63.      * @throws RuntimeException If an appropriate mixing strategy isn't found
  64.      *
  65.      * @return Generator The instantiated generator
  66.      */
  67.     public function getGenerator(\SecurityLib\Strength $strength)
  68.     {
  69.         $sources $this->findSources($strength);
  70.         $mixer   $this->findMixer($strength);
  71.         return new Generator($sources$mixer);
  72.     }
  73.     /**
  74.      * Get a high strength random number generator
  75.      *
  76.      * High Strength keys should ONLY be used for generating extremely strong
  77.      * cryptographic keys.  Generating them is very resource intensive and may
  78.      * take several minutes or more depending on the requested size.
  79.      *
  80.      * @return Generator The instantiated generator
  81.      */
  82.     public function getHighStrengthGenerator()
  83.     {
  84.         return $this->getGenerator(new Strength(Strength::HIGH));
  85.     }
  86.     /**
  87.      * Get a low strength random number generator
  88.      *
  89.      * Low Strength should be used anywhere that random strings are needed in a
  90.      * non-cryptographical setting.  They are not strong enough to be used as
  91.      * keys or salts.  They are however useful for one-time use tokens.
  92.      *
  93.      * @return Generator The instantiated generator
  94.      */
  95.     public function getLowStrengthGenerator()
  96.     {
  97.         return $this->getGenerator(new Strength(Strength::LOW));
  98.     }
  99.     /**
  100.      * Get a medium strength random number generator
  101.      *
  102.      * Medium Strength should be used for most needs of a cryptographic nature.
  103.      * They are strong enough to be used as keys and salts.  However, they do
  104.      * take some time and resources to generate, so they should not be over-used
  105.      *
  106.      * @return Generator The instantiated generator
  107.      */
  108.     public function getMediumStrengthGenerator()
  109.     {
  110.         return $this->getGenerator(new Strength(Strength::MEDIUM));
  111.     }
  112.     /**
  113.      * Get all loaded mixing strategies
  114.      *
  115.      * @return array An array of mixers
  116.      */
  117.     public function getMixers()
  118.     {
  119.         return $this->mixers;
  120.     }
  121.     /**
  122.      * Get all loaded random number sources
  123.      *
  124.      * @return array An array of sources
  125.      */
  126.     public function getSources()
  127.     {
  128.         return $this->sources;
  129.     }
  130.     /**
  131.      * Register a mixing strategy for this factory instance
  132.      *
  133.      * @param string $name  The name of the stategy
  134.      * @param string $class The class name of the implementation
  135.      *
  136.      * @return Factory $this The current factory instance
  137.      */
  138.     public function registerMixer($name$class)
  139.     {
  140.         $this->registerType(
  141.             'mixers',
  142.             __NAMESPACE__ '\\Mixer',
  143.             $name,
  144.             $class
  145.         );
  146.         return $this;
  147.     }
  148.     /**
  149.      * Register a random number source for this factory instance
  150.      *
  151.      * Note that this class must implement the Source interface
  152.      *
  153.      * @param string $name  The name of the stategy
  154.      * @param string $class The class name of the implementation
  155.      *
  156.      * @return Factory $this The current factory instance
  157.      */
  158.     public function registerSource($name$class)
  159.     {
  160.         $this->registerType(
  161.             'sources',
  162.             __NAMESPACE__ '\\Source',
  163.             $name,
  164.             $class
  165.         );
  166.         return $this;
  167.     }
  168.     /**
  169.      * Find a sources based upon the requested strength
  170.      *
  171.      * @param Strength $strength The strength mixer to find
  172.      *
  173.      * @throws RuntimeException if a valid source cannot be found
  174.      *
  175.      * @return Source The found source
  176.      */
  177.     protected function findSources(\SecurityLib\Strength $strength)
  178.     {
  179.         $sources = array();
  180.         foreach ($this->getSources() as $source) {
  181.             if ($strength->compare($source::getStrength()) <= && $source::isSupported()) {
  182.                 $sources[] = new $source();
  183.             }
  184.         }
  185.         if (=== count($sources)) {
  186.             throw new \RuntimeException('Could not find sources');
  187.         }
  188.         return $sources;
  189.     }
  190.     /**
  191.      * Find a mixer based upon the requested strength
  192.      *
  193.      * @param Strength $strength The strength mixer to find
  194.      *
  195.      * @throws RuntimeException if a valid mixer cannot be found
  196.      *
  197.      * @return Mixer The found mixer
  198.      */
  199.     protected function findMixer(\SecurityLib\Strength $strength)
  200.     {
  201.         $newMixer null;
  202.         $fallback null;
  203.         foreach ($this->getMixers() as $mixer) {
  204.             if (!$mixer::test()) {
  205.                 continue;
  206.             }
  207.             if ($strength->compare($mixer::getStrength()) == 0) {
  208.                 $newMixer = new $mixer();
  209.             } elseif ($strength->compare($mixer::getStrength()) == 1) {
  210.                 $fallback = new $mixer();
  211.             }
  212.         }
  213.         if (is_null($newMixer)) {
  214.             if (is_null($fallback)) {
  215.                 throw new \RuntimeException('Could not find mixer');
  216.             }
  217.             return $fallback;
  218.         }
  219.         return $newMixer;
  220.     }
  221.     /**
  222.      * Load all core mixing strategies
  223.      *
  224.      * @return void
  225.      */
  226.     protected function loadMixers()
  227.     {
  228.         $this->loadFiles(
  229.             __DIR__ '/Mixer',
  230.             __NAMESPACE__ '\\Mixer\\',
  231.             array($this'registerMixer')
  232.         );
  233.     }
  234.     /**
  235.      * Load all core random number sources
  236.      *
  237.      * @return void
  238.      */
  239.     protected function loadSources()
  240.     {
  241.         $this->loadFiles(
  242.             __DIR__ '/Source',
  243.             __NAMESPACE__ '\\Source\\',
  244.             array($this'registerSource')
  245.         );
  246.     }
  247. }