大随机数生成

时间:2010-09-11 13:14:13

标签: php random

我需要一个PHP中的大型(比方说,128位大)随机数生成器。我正在考虑将这个数字存储在一个十六进制的字符串中。

请注意,这适用于提到需要“随机”号码的登录系统,所以我猜我真的需要它“随机”(因为我知道)伪随机永远不会真正随机。)

我想的算法是一次生成第一个十六进制数字,然后将它连接起来。像这样:

$random = '';
for ($i = 0; $i < 32; ++$i) {
   $digit = rand(0, 15);
   $random .= ($digit < 10 ? $digit : ($digit - 10 + 'a'));
}
return $random;

我能相信这个函数能够返回好的伪随机数吗?还是我搞砸了一些我真的不应该做的事情?

4 个答案:

答案 0 :(得分:4)

尝试:

for ($str = '', $i = 0; $i < $len; $i++) {
    $str .= dechex(mt_rand(0, 15));
}

答案 1 :(得分:3)

几年前我问过这个问题,从那时起,我对这个主题的了解有所改善。

首先,我提到我想要一个登录系统的随机数字。登录系统是安全机制。 这意味着登录系统依赖的任何随机数生成器都应该加密安全

PHP的randmt_rand在加密方面不安全。

在这些情况下,最好是安全而不是抱歉。有一些随机数生成器专门设计为安全的,特别是openssl_random_pseudo_bytes(遗憾的是并不总是可用 - 您必须启用OpenSSL扩展才能使其正常工作)。在* NIX系统(例如Linux)上,字节也从/dev/urandom can be used读取。

不幸的是(出于这个问题的目的),这两种方法都返回二进制数据而不是十六进制数据。幸运的是,PHP已经有了一个函数来解决这个问题,bin2hex,适用于任何长度的字符串。

所以这里是代码的样子:

function generate_secure_random_hex_string($length) {
   // $length should be an even, non-negative number.

   // Because each byte is represented as two hex digits, we'll need the binary
   // string to be half as long as the hex string.
   $binary_length = $length / 2;

   // First, we'll generate the random binary string.
   $random_result = openssl_random_pseudo_bytes($binary_length, $cstrong);

   if (!$cstrong) {
      // The result is not cryptographically secure. Abort.
      // die() is just a placeholder.
      // There might be better ways to handle this error.
      die();
   }

   //Convert the result to hexadecimal
   return bin2hex($random_result);
}

// Example:
echo generate_secure_random_hex_string(32);

答案 2 :(得分:1)

我经常看到这在登录系统中通过执行以下操作来处理:

$salt  = "big string of random stuff"; // you can generate this once like above
$token = md5( $salt . time()); // this will be your "unique" number

MD5哈希可能会发生冲突,但这非常有效且非常简单。

答案 3 :(得分:0)

从PHP 5.3开始:

function getRandomHex($num_bytes=4) {
  return bin2hex(openssl_random_pseudo_bytes($num_bytes));
}

以128位为例:

$rand128 = getRandomHex(16);