/Data/RandomStringGenerator.php

https://bitbucket.org/spidgorny/nadlib · PHP · 172 lines · 95 code · 33 blank · 44 comment · 15 complexity · 22769f2ae19c50d2e36bf4bcba11a492 MD5 · raw file

  1. <?php
  2. /**
  3. * Class RandomStringGenerator
  4. * @package Utils
  5. *
  6. * Solution taken from here:
  7. * http://stackoverflow.com/a/13733588/1056679
  8. */
  9. class RandomStringGenerator
  10. {
  11. /** @var string */
  12. protected $alphabet;
  13. /** @var int */
  14. protected $alphabetLength;
  15. /**
  16. * @param string $alphabet
  17. */
  18. public function __construct($alphabet = '')
  19. {
  20. if ('' !== $alphabet) {
  21. $this->setAlphabet($alphabet);
  22. } else {
  23. $this->setAlphabet(
  24. implode(range('a', 'z'))
  25. . implode(range('A', 'Z'))
  26. . implode(range(0, 9))
  27. );
  28. }
  29. }
  30. /**
  31. * @param string $alphabet
  32. */
  33. public function setAlphabet($alphabet)
  34. {
  35. $this->alphabet = $alphabet;
  36. $this->alphabetLength = strlen($alphabet);
  37. }
  38. /**
  39. * @param int $length
  40. * @return string
  41. */
  42. public function generate($length)
  43. {
  44. $token = '';
  45. for ($i = 0; $i < $length; $i++) {
  46. $randomKey = $this->getRandomInteger(0, $this->alphabetLength);
  47. $token .= $this->alphabet[$randomKey];
  48. }
  49. return $token;
  50. }
  51. /**
  52. * @param int $min
  53. * @param int $max
  54. * @return int
  55. */
  56. protected function getRandomInteger($min, $max)
  57. {
  58. $range = ($max - $min);
  59. if ($range < 0) {
  60. // Not so random...
  61. return $min;
  62. }
  63. $log = log($range, 2);
  64. // Length in bytes.
  65. $bytes = (int) ($log / 8) + 1;
  66. // Length in bits.
  67. $bits = (int) $log + 1;
  68. // Set all lower bits to 1.
  69. $filter = (int) (1 << $bits) - 1;
  70. do {
  71. $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
  72. // Discard irrelevant bits.
  73. $rnd = $rnd & $filter;
  74. } while ($rnd >= $range);
  75. return ($min + $rnd);
  76. }
  77. function generateSplit4($length) {
  78. $continuous = $this->generate($length);
  79. $parts = chunk_split($continuous, 4, '-');
  80. if ($parts[strlen($parts)-1] == '-') {
  81. $parts = substr($parts, 0, strlen($parts) - 1);
  82. }
  83. return $parts;
  84. }
  85. static function likeYouTube() {
  86. $gen = new self();
  87. return $gen->generate(10);
  88. }
  89. /**
  90. * http://www.anyexample.com/programming/php/php__password_generation.xml
  91. * @param int $syllables
  92. * @return string
  93. */
  94. public function generateReadablePassword($syllables = 3) {
  95. $use_prefix = false;
  96. // Define function unless it is already exists
  97. if (!function_exists('ae_arr')) {
  98. // This function returns random array element
  99. function ae_arr(&$arr) {
  100. return $arr[rand(0, sizeof($arr)-1)];
  101. }
  102. }
  103. // 20 prefixes
  104. $prefix = array('aero', 'anti', 'auto', 'bi', 'bio',
  105. 'cine', 'deca', 'demo', 'dyna', 'eco',
  106. 'ergo', 'geo', 'gyno', 'hypo', 'kilo',
  107. 'mega', 'tera', 'mini', 'nano', 'duo');
  108. // 10 random suffixes
  109. $suffix = array('dom', 'ity', 'ment', 'sion', 'ness',
  110. 'ence', 'er', 'ist', 'tion', 'or');
  111. // 8 vowel sounds
  112. $vowels = array('a', 'o', 'e', 'i', 'y', 'u', 'ou', 'oo');
  113. // 20 random consonants
  114. $consonants = array('w', 'r', 't', 'p', 's', 'd', 'f', 'g', 'h', 'j',
  115. 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'qu');
  116. $password = $use_prefix?ae_arr($prefix):'';
  117. $password_suffix = ae_arr($suffix);
  118. for($i=0; $i<$syllables; $i++)
  119. {
  120. // selecting random consonant
  121. $doubles = array('n', 'm', 't', 's');
  122. $c = ae_arr($consonants);
  123. if (in_array($c, $doubles)&&($i!=0)) { // maybe double it
  124. if (rand(0, 2) == 1) // 33% probability
  125. $c .= $c;
  126. }
  127. $password .= $c;
  128. //
  129. // selecting random vowel
  130. $password .= ae_arr($vowels);
  131. if ($i == $syllables - 1) // if suffix begin with vovel
  132. if (in_array($password_suffix[0], $vowels)) // add one more consonant
  133. $password .= ae_arr($consonants);
  134. }
  135. // selecting random suffix
  136. $password .= $password_suffix;
  137. return $password;
  138. }
  139. }