PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/library/utility/phpseclib/Crypt/Random.php

https://github.com/cuijinquan/nextwind
PHP | 129 lines | 52 code | 9 blank | 68 comment | 9 complexity | 4bc24aeb22af3fc2e9afcf0ff004085e MD5 | raw file
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Random Number Generator
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * Here's a short example of how to use this library:
  9. * <code>
  10. * <?php
  11. * include('Crypt/Random.php');
  12. *
  13. * echo crypt_random();
  14. * ?>
  15. * </code>
  16. *
  17. * LICENSE: This library is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU Lesser General Public
  19. * License as published by the Free Software Foundation; either
  20. * version 2.1 of the License, or (at your option) any later version.
  21. *
  22. * This library is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. * Lesser General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU Lesser General Public
  28. * License along with this library; if not, write to the Free Software
  29. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30. * MA 02111-1307 USA
  31. *
  32. * @category Crypt
  33. * @package Crypt_Random
  34. * @author Jim Wigginton <terrafrost@php.net>
  35. * @copyright MMVII Jim Wigginton
  36. * @license http://www.gnu.org/licenses/lgpl.txt
  37. * @version $Id: Random.php 21939 2012-12-17 07:13:16Z long.shi $
  38. * @link http://phpseclib.sourceforge.net
  39. */
  40. /**
  41. * Generate a random value.
  42. *
  43. * On 32-bit machines, the largest distance that can exist between $min and $max is 2**31.
  44. * If $min and $max are farther apart than that then the last ($max - range) numbers.
  45. *
  46. * Depending on how this is being used, it may be worth while to write a replacement. For example,
  47. * a PHP-based web app that stores its data in an SQL database can collect more entropy than this function
  48. * can.
  49. *
  50. * @param optional Integer $min
  51. * @param optional Integer $max
  52. * @return Integer
  53. * @access public
  54. */
  55. function crypt_random($min = 0, $max = 0x7FFFFFFF)
  56. {
  57. if ($min == $max) {
  58. return $min;
  59. }
  60. // see http://en.wikipedia.org/wiki//dev/random
  61. // if open_basedir is enabled file_exists() will ouput an "open_basedir restriction in effect" warning,
  62. // so we suppress it.
  63. if (@file_exists('/dev/urandom')) {
  64. static $fp;
  65. if (!$fp) {
  66. $fp = fopen('/dev/urandom', 'rb');
  67. }
  68. extract(unpack('Nrandom', fread($fp, 4)));
  69. // say $min = 0 and $max = 3. if we didn't do abs() then we could have stuff like this:
  70. // -4 % 3 + 0 = -1, even though -1 < $min
  71. return abs($random) % ($max - $min) + $min;
  72. }
  73. /* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.
  74. Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:
  75. http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
  76. The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:
  77. http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_2/ext/standard/php_rand.h?view=markup */
  78. if (version_compare(PHP_VERSION, '5.2.5', '<=')) {
  79. static $seeded;
  80. if (!isset($seeded)) {
  81. $seeded = true;
  82. mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));
  83. }
  84. }
  85. static $crypto;
  86. // The CSPRNG's Yarrow and Fortuna periodically reseed. This function can be reseeded by hitting F5
  87. // in the browser and reloading the page.
  88. if (!isset($crypto)) {
  89. $key = $iv = '';
  90. for ($i = 0; $i < 8; $i++) {
  91. $key.= pack('n', mt_rand(0, 0xFFFF));
  92. $iv .= pack('n', mt_rand(0, 0xFFFF));
  93. }
  94. switch (true) {
  95. case class_exists('Crypt_AES'):
  96. $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
  97. break;
  98. case class_exists('Crypt_TripleDES'):
  99. $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
  100. break;
  101. case class_exists('Crypt_DES'):
  102. $crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
  103. break;
  104. case class_exists('Crypt_RC4'):
  105. $crypto = new Crypt_RC4();
  106. break;
  107. default:
  108. extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF)))));
  109. return abs($random) % ($max - $min) + $min;
  110. }
  111. $crypto->setKey($key);
  112. $crypto->setIV($iv);
  113. $crypto->enableContinuousBuffer();
  114. }
  115. extract(unpack('Nrandom', $crypto->encrypt("\0\0\0\0")));
  116. return abs($random) % ($max - $min) + $min;
  117. }