8889841cPK/[GeneratorInterface.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen; interface GeneratorInterface { /** * Outputs a generated key including the prefix and suffix if any. * May also return transformed keys. * * @return string */ public function generate(); } PK/[t@@GeneratorFactory.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen; use InvalidArgumentException; class GeneratorFactory { /** * Create a generator instance from the specified type. * * @param string $type Generator type. * @return Keygen\Generator * * @throws \InvalidArgumentException */ public static function create($type) { $generator = sprintf("Keygen\Generators\%sGenerator", ucfirst($type)); if (class_exists($generator)) { $generator = new $generator; if ($generator instanceof Generator) { return $generator; } } throw new InvalidArgumentException('Cannot create unknown generator type.'); } } PK/[ÑccTraits/GeneratorMutation.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Traits; use InvalidArgumentException; use Keygen\AbstractGenerator; trait GeneratorMutation { use FlattenArguments; /** * A collection of mutable generators to receive property mutations. * * @var array */ protected $mutates = []; /** * Object difference comparator using array_diff callback. * * @param array $array1 * @param array $array2 * @return array */ private static function objectDiffInArrays($array1, $array2) { return array_udiff($array1, $array2, function($a, $b) { if ($a === $b) { return 0; } elseif ($a < $b) { return -1; } elseif ($a > $b) { return 1; } }); } /** * Add mutable generators to the mutates collection * * @param mixed $objects * @return $this * * @throws \InvalidArgumentException */ public function mutate($objects) { $objects = call_user_func_array(array($this, 'flattenArguments'), func_get_args()); $collect = []; foreach ($objects as $obj) { if ($obj instanceof AbstractGenerator) { array_push($collect, $obj); continue; } throw new InvalidArgumentException(sprintf('Mutable objects must be instances of %s.', AbstractGenerator::class)); } $this->mutates = array_merge(static::objectDiffInArrays($this->mutates, $collect), $collect); return $this; } /** * Remove generators from the mutates collection * * @param mixed $objects * @return $this */ public function dontMutate($objects) { $objects = call_user_func_array(array($this, 'flattenArguments'), func_get_args()); $this->mutates = static::objectDiffInArrays($this->mutates, $objects); return $this; } } PK/[.Traits/FlattenArguments.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Traits; trait FlattenArguments { /** * Flattens its arguments array into a simple array. * * @return array */ protected function flattenArguments() { $args = func_get_args(); $flat = []; foreach ($args as $arg) { if (is_array($arg)) { $flat = call_user_func_array(array($this, 'flattenArguments'), array_merge($flat, $arg)); continue; } array_push($flat, $arg); } return $flat; } } PK/[*"Traits/IntegerCasting.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Traits; use InvalidArgumentException; trait IntegerCasting { /** * Casts the given value into an integer and returns the integer. * Throws an exception if value cannot be casted to an integer. * * @param mixed $value * @return int * * @throws \InvalidArgumentException */ protected function intCast($value) { if (is_numeric($value)) { return intval($value); } throw new InvalidArgumentException('The given value cannot be converted to an integer.'); } } PK/[^i}22Traits/MutableGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Traits; use InvalidArgumentException; use Keygen\AbstractGenerator; trait MutableGenerator { use FlattenArguments; /** * A collection of mutable attributes. * * @var array */ protected $mutables = []; /** * Add mutable attributes to the mutables collection * * @param mixed $props * @return $this * * @throws \InvalidArgumentException */ public function mutable($props) { $props = call_user_func_array(array($this, 'flattenArguments'), func_get_args()); $collect = $unknown = []; foreach ($props as $prop) { if (!property_exists(AbstractGenerator::class, $prop)) { array_push($unknown, $prop); continue; } array_push($collect, $prop); } if (!empty($unknown)) { throw new InvalidArgumentException(sprintf("Cannot add unknown %s to mutables collection ('%s').", (count($unknown) > 1) ? 'properties' : 'property', join("', '", $unknown))); } $this->mutables = array_merge(array_diff($this->mutables, $collect), $collect); return $this; } /** * Remove attributes from the mutables collection * * @param mixed $props * @return $this */ public function immutable($props) { $props = call_user_func_array(array($this, 'flattenArguments'), func_get_args()); $this->mutables = array_diff($this->mutables, $props); return $this; } } PK/[zI Traits/KeyManipulation.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Traits; use BadMethodCallException; use InvalidArgumentException; trait KeyManipulation { use IntegerCasting; /** * Length of keys to be generated by the generator. * * @var int */ protected $length; /** * Key prefix. * * @var string */ protected $prefix; /** * Key suffix. * * @var string */ protected $suffix; /** * Propagates property mutation to listed mutable generators. * * @param string $prop * @param bool $propagate * @return $this */ protected function propagateMutation($prop, $propagate) { $propagate = !is_bool($propagate) ? true : $propagate; if ($propagate && isset($this->mutates)) { foreach ($this->mutates as $obj) { if (in_array($prop, $obj->mutables)) { call_user_func(array($obj, $prop), $this->{$prop}); } } } return $this; } /** * Sets the length of keys to be generated by the generator. * * @param numeric $length * @param bool $propagate * @return $this * * @throws \InvalidArgumentException */ protected function length($length, $propagate = true) { $this->length = $this->intCast($length ?: $this->length); return $this->propagateMutation('length', $propagate); } /** * Affixes string to generated keys. * * @param string $affix Affix type (either 'prefix' or 'suffix') * @param string $value * @param bool $propagate * @return $this * * @throws \InvalidArgumentException */ protected function affix($affix, $value, $propagate = true) { $affixes = ['prefix', 'suffix']; if (in_array($affix, $affixes)) { if (is_scalar($value)) { $this->{$affix} = strval($value); return $this->propagateMutation($affix, $propagate); } throw new InvalidArgumentException("The given {$affix} cannot be converted to a string."); } } /** * Prepends string to generated keys. * * @param string $prefix * @param bool $propagate * @return $this * * @throws \InvalidArgumentException */ protected function prefix($prefix, $propagate = true) { return $this->affix('prefix', $prefix, $propagate); } /** * Appends string to generated keys. * * @param string $suffix * @param bool $propagate * @return $this * * @throws \InvalidArgumentException */ protected function suffix($suffix, $propagate = true) { return $this->affix('suffix', $suffix, $propagate); } /** * Gets the key length less the prefix length and suffix length. * * @return int */ protected function getAdjustedKeyLength() { return $this->length - intval(strlen($this->prefix) + strlen($this->suffix)); } /** * Overload helper for internal method calls. * * @param string $method * @param array $args * @return $this * * @throws \BadMethodCallException */ protected function __overloadMethods($method, $args) { $_method = strtolower($method); if (in_array($_method, ['prefix', 'suffix'])) { return call_user_func_array(array($this, 'affix'), array_merge([$_method], $args)); } if ($_method == 'length') { return call_user_func_array(array($this, 'length'), $args); } throw new BadMethodCallException(sprintf("Call to unknown method %s::%s()", get_called_class(), $method)); } } PK/[pJxx Keygen.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen; /** * @method static Generator token(int $length) * @method static Generator numeric(int $length) * @method static Generator alphanum(int $length) * @method static Generator bytes(int $length) */ class Keygen extends AbstractGenerator { /** * Creates a new generator instance of the given type. * * @param string $type Generator type * @param mixed $length * @return Keygen\Generator * * @throws \InvalidArgumentException */ protected function newGenerator($type, $length = null) { $generator = GeneratorFactory::create($type)->mutate($this)->length($length ?: $this->length); if (isset($this->prefix)) { $generator->prefix($this->prefix); } if (isset($this->suffix)) { $generator->suffix($this->suffix); } return $generator; } /** * Creates a new generator instance from the given alias. * * @param string $alias Generator type alias * @param mixed $length * @return Keygen\Generator | null * * @throws \InvalidArgumentException */ protected function newGeneratorFromAlias($alias, $length = null) { $generatorAliases = [ 'numeric' => 'numeric', 'alphanum' => 'alphaNumeric', 'token' => 'token', 'bytes' => 'randomByte' ]; if (array_key_exists($alias, $generatorAliases)) { return $this->newGenerator($generatorAliases[$alias], $length); } } /** * Overload the __call method */ public function __call($method, $args) { $_method = strtolower($method); $generator = $this->newGeneratorFromAlias($_method, isset($args[0]) ? $args[0] : null); if ($generator instanceof Generator) { return $generator; } return parent::__call($method, $args); } } PK/[W%w Generator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen; abstract class Generator extends AbstractGenerator implements GeneratorInterface { /** * Generates a random key. * * @param numeric $length * @return string */ abstract protected function keygen($length); /** * Outputs a generated key including the prefix and suffix if any. * May also return transformed keys. * * @return string */ public function generate() { $args = func_get_args(); $useKeyLength = array_shift($args); if (!is_bool($useKeyLength)) { array_unshift($args, $useKeyLength); $useKeyLength = false; } $callables = call_user_func_array(array($this, 'flattenArguments'), $args); $key = $this->keygen($useKeyLength ? $this->length : $this->getAdjustedKeyLength()); while ($callable = current($callables)) { if (is_callable($callable)) { $key = call_user_func($callable, $key); } next($callables); } return sprintf("%s%s%s", $this->prefix, $key, $this->suffix); } } PK/[_iGenerators/NumericGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Generators; use Keygen\Generator; class NumericGenerator extends Generator { /** * Generates a random key. * * @param numeric $length * @return string */ protected function keygen($length) { $chars = str_shuffle('3759402687094152031368921'); $chars = str_shuffle(str_repeat($chars, ceil($length / strlen($chars)))); return strrev(str_shuffle(substr($chars, mt_rand(0, (strlen($chars) - $length - 1)), $length))); } } PK/[e'8$Generators/AlphaNumericGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Generators; use Keygen\Generator; class AlphaNumericGenerator extends Generator { /** * Generates a random key. * * @param numeric $length * @return string */ protected function keygen($length) { $key = ''; $chars = array_merge(range(0, 9), range('a', 'z'), range(0, 9), range('A', 'Z'), range(0, 9)); shuffle($chars); $chars = str_shuffle(str_rot13(join('', $chars))); $split = intval(ceil($length / 5)); $size = strlen($chars); $splitSize = ceil($size / $split); $chunkSize = 5 + $splitSize + mt_rand(1, 5); $chunkArray = array(); $chars = str_shuffle(str_repeat($chars, 2)); $size = strlen($chars); while ($split != 0) { $strip = substr($chars, mt_rand(0, $size - $chunkSize), $chunkSize); array_push($chunkArray, strrev($strip)); $split--; } foreach ($chunkArray as $set) { $modulus = ($length - strlen($key)) % 5; $adjusted = ($modulus > 0) ? $modulus : 5; $key .= substr($set, mt_rand(0, strlen($set) - $adjusted), $adjusted); } return str_rot13(str_shuffle($key)); } } PK/[HGenerators/TokenGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Generators; use Keygen\Generator; class TokenGenerator extends Generator { /** * Generates a random key. * * @param numeric $length * @return string */ protected function keygen($length) { $token = ''; $tokenlength = round($length * 4 / 3); for ($i = 0; $i < $tokenlength; ++$i) { $token .= chr(rand(32,1024)); } $token = base64_encode(str_shuffle($token)); return substr($token, 0, $length); } } PK/[&AYss"Generators/RandomByteGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen\Generators; use RuntimeException; use Keygen\Generator; class RandomByteGenerator extends Generator { /** * Hexadecimal output enabled. * * @var bool */ protected $hex = false; /** * Enables hexadecimal output of byte string. * * @return $this */ public function hex() { $this->hex = true; return $this; } /** * Generates a random key. * * @param numeric $length * @return string * * @throws \RuntimeException */ protected function keygen($length) { $hex = !is_bool($this->hex) ?: $this->hex; $bytelength = $hex ? ceil($length / 2) : $length; if (function_exists('random_bytes')) { $bytes = random_bytes($bytelength); } elseif (function_exists('openssl_random_pseudo_bytes')) { $bytes = openssl_random_pseudo_bytes($bytelength); } elseif (@file_exists('/dev/urandom') && $bytelength < 100) { $bytes = file_get_contents('/dev/urandom', false, null, 0, $bytelength); } else { throw new RuntimeException('Cannot generate binary data.'); } return $hex ? substr(bin2hex($bytes), 0, $length) : $bytes; } /** * Outputs a generated key including the prefix and suffix if any. * May also return transformed keys. * * @return string */ public function generate() { $key = call_user_func_array('parent::generate', func_get_args()); if ($this->hex === true) { $this->hex = false; } return $key; } } PK/[[AbstractGenerator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Keygen; use Keygen\Traits\KeyManipulation; use Keygen\Traits\MutableGenerator; use Keygen\Traits\GeneratorMutation; abstract class AbstractGenerator { use KeyManipulation, MutableGenerator, GeneratorMutation { MutableGenerator::flattenArguments insteadof GeneratorMutation; } /** * Creates a new KeyGenerator instance. * * @param mixed $length * * @throws \InvalidArgumentException */ public function __construct($length = 16) { $this->length($length); } /** * Overload the __isset method */ public function __isset($prop) { return array_key_exists($prop, get_object_vars($this)); } /** * Overload the __get method */ public function __get($prop) { if (isset($this->{$prop})) { return $this->{$prop}; } } /** * Overload the __call method */ public function __call($method, $args) { return $this->__overloadMethods($method, $args); } /** * Overload the __callStatic method */ public static function __callStatic($method, $args) { return (new static)->__call($method, $args); } } PK/[GeneratorInterface.phpnu[PK/[t@@ GeneratorFactory.phpnu[PK/[ÑccTraits/GeneratorMutation.phpnu[PK/[.> Traits/FlattenArguments.phpnu[PK/[*"+Traits/IntegerCasting.phpnu[PK/[^i}22UTraits/MutableGenerator.phpnu[PK/[zI Traits/KeyManipulation.phpnu[PK/[pJxx 'Keygen.phpnu[PK/[W%w ]/Generator.phpnu[PK/[_iI4Generators/NumericGenerator.phpnu[PK/[e'8$L7Generators/AlphaNumericGenerator.phpnu[PK/[H<Generators/TokenGenerator.phpnu[PK/[&AYss"?Generators/RandomByteGenerator.phpnu[PK/[[lFAbstractGenerator.phpnu[PKK