Advertisement
Guest User

Second version

a guest
Jan 30th, 2012
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 2.79 KB | None | 0 0
  1. /**
  2.  * Generate pseudo random bits using the best available method.
  3.  *
  4.  * @param int $bits Amount of random bits to generate.
  5.  * @param bool $secure Use a cryptographically secure method of getting these random bits.
  6.  * @param int $output_type The output type for the generated bits.
  7.  * @return string A (pseudo) random string.
  8.  *
  9.  * @copyright: public domain
  10.  * @author Beanow
  11.  * @link http://tuxion.nl
  12.  * @note Don't try to improve this, you will likely just ruin it
  13.  * @note I did it anyways. Regards ~Beanow
  14.  */
  15. private function _random_bits($bits, $secure=true, $output_type=self::OUTPUT_HEX)
  16. {
  17.  
  18.   //Obviously *NIX is for pro's and so we should use it's generator if available.
  19.   //Ok the real reason is that it gives high entropy by gathering noise on an OS level.
  20.   //So using that makes this function a lot faster and more safe.
  21.   if (@is_readable('/dev/urandom')){
  22.     $f=fopen('/dev/urandom', 'rb');
  23.     $str=fread($f, ceil($bits/8));
  24.     fclose($f);
  25.     return $this->_convert_bin($str, $output_type);
  26.   }
  27.  
  28.   //If we don't have it we're going to make the best out of getting microtime() bits of randomness.
  29.   else
  30.   {
  31.    
  32.     //Generate more entropy starting state, to give it that extra bit of spunk. :D
  33.     $state = uniqid('', true);
  34.     $intermediate_bytes = '';
  35.     $random_bytes = '';
  36.     $hash_algoritm = $this->pref_hash_algo($bits, true, $intermediate_bits);
  37.     $intermediate_hashes = 0;
  38.    
  39.     //Increment with 20, because microtime() generates 6 decimals which is almost 20 bits.
  40.     //The fraction of the last bit that isn't available from microtime() comes from mt_rand().
  41.     //However if $secure is set to false we don't care and take the size of the hash output instead.
  42.     //This will make the algorithm faster but will contain much less (~60%) entropy.
  43.     //Note that the state hash and string appending hash are different and should be!
  44.     //It makes it impossible for the state to leak into the output stream.
  45.     for ($entropy = 0; $entropy < $bits; $entropy += ($secure === true ? 20 : 52))
  46.     {
  47.    
  48.       $state = $this->hash(microtime().$state.mt_rand(), self::$HASH_PREFERENCES['128'][0]);
  49.       $intermediate_bytes .= $this->hash(microtime().$state, self::$HASH_PREFERENCES['128'][0], self::OUTPUT_BINARY);
  50.      
  51.       //Whenever we have reached the max entropy we can cram into the hashing algorithm that was selected, hash it to the results.
  52.       //Use bytes here so we don't get pointless data in here, like padding signs for base64.
  53.       if($entropy >= ($intermediate_bits * ($intermediate_hashes+1))){
  54.         $random_bytes .= $this->hash($intermediate_bytes, $hash_algoritm, self::OUTPUT_BINARY);
  55.       }
  56.      
  57.     }
  58.    
  59.     //Do final conversion of binary data.
  60.     return $this->_convert_bin($random_bytes, $output_type);
  61.    
  62.   }
  63.  
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement