1*c3437056SNickeau<?php 2*c3437056SNickeaunamespace Hidehalo\Nanoid; 3*c3437056SNickeau 4*c3437056SNickeauclass Client 5*c3437056SNickeau{ 6*c3437056SNickeau /** 7*c3437056SNickeau * Random mode flags 8*c3437056SNickeau * 9*c3437056SNickeau * @const MODE_NORMAL 1 10*c3437056SNickeau * @const MODEL_DYNAMIC 2 11*c3437056SNickeau */ 12*c3437056SNickeau const MODE_NORMAL = 1; 13*c3437056SNickeau const MODE_DYNAMIC = 2; 14*c3437056SNickeau /** 15*c3437056SNickeau * @param string $alphabet Symbols to be used in ID. 16*c3437056SNickeau * @param integer $size number of symbols in ID. 17*c3437056SNickeau */ 18*c3437056SNickeau protected $alphbet; 19*c3437056SNickeau protected $size; 20*c3437056SNickeau 21*c3437056SNickeau /** 22*c3437056SNickeau * @var CoreInterface $core Core dynamic random 23*c3437056SNickeau */ 24*c3437056SNickeau private $core; 25*c3437056SNickeau /** 26*c3437056SNickeau * @var GeneratorInterface $generator Random Btyes Generator 27*c3437056SNickeau */ 28*c3437056SNickeau protected $generator; 29*c3437056SNickeau 30*c3437056SNickeau /** 31*c3437056SNickeau * Constructor of Client 32*c3437056SNickeau * 33*c3437056SNickeau * @codeCoverageIgnore 34*c3437056SNickeau * @param integer $size 35*c3437056SNickeau * @param GeneratorInterface $generator 36*c3437056SNickeau */ 37*c3437056SNickeau public function __construct($size = 21, GeneratorInterface $generator = null) 38*c3437056SNickeau { 39*c3437056SNickeau $this->size = $size > 0 ? $size : 21; 40*c3437056SNickeau $this->generator = $generator?:new Generator(); 41*c3437056SNickeau $this->core = new Core(); 42*c3437056SNickeau $this->alphbet = CoreInterface::SAFE_SYMBOLS; 43*c3437056SNickeau } 44*c3437056SNickeau 45*c3437056SNickeau /** 46*c3437056SNickeau * Generate nanoid via optional modes 47*c3437056SNickeau * 48*c3437056SNickeau * @param integer $size 49*c3437056SNickeau * @param integer $mode Client::MODE_NORMAL|Client::MODE_DYNAMIC 50*c3437056SNickeau * @return string 51*c3437056SNickeau */ 52*c3437056SNickeau public function generateId($size = 0, $mode = self::MODE_NORMAL) 53*c3437056SNickeau { 54*c3437056SNickeau $size = $size>0? $size: $this->size; 55*c3437056SNickeau switch ($mode) { 56*c3437056SNickeau case self::MODE_DYNAMIC: 57*c3437056SNickeau return $this->core->random($this->generator, $size, $this->alphbet); 58*c3437056SNickeau default: 59*c3437056SNickeau return $this->normalRandom($size); 60*c3437056SNickeau } 61*c3437056SNickeau } 62*c3437056SNickeau 63*c3437056SNickeau /** 64*c3437056SNickeau * The original API of nanoid. Use it be careful, Please make sure 65*c3437056SNickeau * you have been implements your custom GeneratorInterface as correctly. 66*c3437056SNickeau * Otherwise use the build-in default random bytes generator 67*c3437056SNickeau * 68*c3437056SNickeau * @param GeneratorInterface $generator 69*c3437056SNickeau * @param integer $size 70*c3437056SNickeau * @param string $alphabet default CoreInterface::SAFE_SYMBOLS 71*c3437056SNickeau * @return string 72*c3437056SNickeau */ 73*c3437056SNickeau public function formattedId($alphabet, $size = 0, GeneratorInterface $generator = null) 74*c3437056SNickeau { 75*c3437056SNickeau $alphabet = $alphabet?:CoreInterface::SAFE_SYMBOLS; 76*c3437056SNickeau $size = $size>0? $size: $this->size; 77*c3437056SNickeau $generator = $generator?:$this->generator; 78*c3437056SNickeau 79*c3437056SNickeau return $this->core->random($generator, $size, $alphabet); 80*c3437056SNickeau } 81*c3437056SNickeau 82*c3437056SNickeau /** 83*c3437056SNickeau * Backwards-compatible method name. 84*c3437056SNickeau * 85*c3437056SNickeau * @param string $alphabet 86*c3437056SNickeau * @param integer $size 87*c3437056SNickeau * @param GeneratorInterface $generator 88*c3437056SNickeau * 89*c3437056SNickeau * @return string 90*c3437056SNickeau * @since 1.0.0 91*c3437056SNickeau */ 92*c3437056SNickeau public function formatedId($alphabet, $size = 0, GeneratorInterface $generator = null) 93*c3437056SNickeau { 94*c3437056SNickeau $size = $size>0? $size: $this->size; 95*c3437056SNickeau 96*c3437056SNickeau return $this->formattedId($alphabet, $size, $generator); 97*c3437056SNickeau } 98*c3437056SNickeau 99*c3437056SNickeau /** 100*c3437056SNickeau * Generate secure URL-friendly unique ID. 101*c3437056SNickeau * By default, ID will have 21 symbols to have same collisions probability 102*c3437056SNickeau * as UUID v4. 103*c3437056SNickeau * 104*c3437056SNickeau * @see https://github.com/ai/nanoid/blob/master/non-secure/index.js#L19 105*c3437056SNickeau * @param integer $size 106*c3437056SNickeau * @return string 107*c3437056SNickeau */ 108*c3437056SNickeau private function normalRandom($size) 109*c3437056SNickeau { 110*c3437056SNickeau $id = ''; 111*c3437056SNickeau while (1 <= $size--) { 112*c3437056SNickeau $rand = mt_rand()/(mt_getrandmax() + 1); 113*c3437056SNickeau $id .= $this->alphbet[$rand*64 | 0]; 114*c3437056SNickeau } 115*c3437056SNickeau 116*c3437056SNickeau return $id; 117*c3437056SNickeau } 118*c3437056SNickeau} 119