You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

172 lines
4.5 KiB

  1. <?php
  2. namespace fast;
  3. /**
  4. * 随机生成类
  5. */
  6. class Random
  7. {
  8. /**
  9. * 生成数字和字母
  10. *
  11. * @param int $len 长度
  12. * @return string
  13. */
  14. public static function alnum($len = 6)
  15. {
  16. return self::build('alnum', $len);
  17. }
  18. /**
  19. * 仅生成字符
  20. *
  21. * @param int $len 长度
  22. * @return string
  23. */
  24. public static function alpha($len = 6)
  25. {
  26. return self::build('alpha', $len);
  27. }
  28. /**
  29. * 生成指定长度的随机数字
  30. *
  31. * @param int $len 长度
  32. * @return string
  33. */
  34. public static function numeric($len = 4)
  35. {
  36. return self::build('numeric', $len);
  37. }
  38. /**
  39. * 数字和字母组合的随机字符串
  40. *
  41. * @param int $len 长度
  42. * @return string
  43. */
  44. public static function nozero($len = 4)
  45. {
  46. return self::build('nozero', $len);
  47. }
  48. /**
  49. * 能用的随机数生成
  50. * @param string $type 类型 alpha/alnum/numeric/nozero/unique/md5/encrypt/sha1
  51. * @param int $len 长度
  52. * @return string
  53. */
  54. public static function build($type = 'alnum', $len = 8)
  55. {
  56. switch ($type) {
  57. case 'alpha':
  58. case 'alnum':
  59. case 'numeric':
  60. case 'nozero':
  61. switch ($type) {
  62. case 'alpha':
  63. $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  64. break;
  65. case 'alnum':
  66. $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  67. break;
  68. case 'numeric':
  69. $pool = '0123456789';
  70. break;
  71. case 'nozero':
  72. $pool = '123456789';
  73. break;
  74. }
  75. return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
  76. case 'unique':
  77. case 'md5':
  78. return md5(uniqid(mt_rand()));
  79. case 'encrypt':
  80. case 'sha1':
  81. return sha1(uniqid(mt_rand(), true));
  82. }
  83. }
  84. /**
  85. * 根据数组元素的概率获得键名
  86. *
  87. * @param array $ps array('p1'=>20, 'p2'=>30, 'p3'=>50);
  88. * @param int $num 默认为1,即随机出来的数量
  89. * @param bool $unique 默认为true,即当num>1时,随机出的数量是否唯一
  90. * @return mixed 当num为1时返回键名,反之返回一维数组
  91. */
  92. public static function lottery($ps, $num = 1, $unique = true)
  93. {
  94. if (!$ps) {
  95. return $num == 1 ? '' : [];
  96. }
  97. if ($num >= count($ps) && $unique) {
  98. $res = array_keys($ps);
  99. return $num == 1 ? $res[0] : $res;
  100. }
  101. $max_exp = 0;
  102. $res = [];
  103. foreach ($ps as $key => $value) {
  104. $value = substr($value, 0, stripos($value, ".") + 6);
  105. $exp = strlen(strchr($value, '.')) - 1;
  106. if ($exp > $max_exp) {
  107. $max_exp = $exp;
  108. }
  109. }
  110. $pow_exp = pow(10, $max_exp);
  111. if ($pow_exp > 1) {
  112. reset($ps);
  113. foreach ($ps as $key => $value) {
  114. $ps[$key] = $value * $pow_exp;
  115. }
  116. }
  117. $pro_sum = array_sum($ps);
  118. if ($pro_sum < 1) {
  119. return $num == 1 ? '' : [];
  120. }
  121. for ($i = 0; $i < $num; $i++) {
  122. $rand_num = mt_rand(1, $pro_sum);
  123. reset($ps);
  124. foreach ($ps as $key => $value) {
  125. if ($rand_num <= $value) {
  126. break;
  127. } else {
  128. $rand_num -= $value;
  129. }
  130. }
  131. if ($num == 1) {
  132. $res = $key;
  133. break;
  134. } else {
  135. $res[$i] = $key;
  136. }
  137. if ($unique) {
  138. $pro_sum -= $value;
  139. unset($ps[$key]);
  140. }
  141. }
  142. return $res;
  143. }
  144. /**
  145. * 获取全球唯一标识
  146. * @return string
  147. */
  148. public static function uuid()
  149. {
  150. return sprintf(
  151. '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  152. mt_rand(0, 0xffff),
  153. mt_rand(0, 0xffff),
  154. mt_rand(0, 0xffff),
  155. mt_rand(0, 0x0fff) | 0x4000,
  156. mt_rand(0, 0x3fff) | 0x8000,
  157. mt_rand(0, 0xffff),
  158. mt_rand(0, 0xffff),
  159. mt_rand(0, 0xffff)
  160. );
  161. }
  162. }