这个PHP代码会生成一个真正随机的密码吗?

时间:2014-01-02 23:48:52

标签: php random

我写了这段代码来生成一个随机密码。

$s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$len = strlen($s);
$m = '';

for ($i = 0; $i < $length; $i ++) {
    $m .= $s[mt_rand(0, $len -1)];
}

return $m;

返回的密码是否真的随机?

3 个答案:

答案 0 :(得分:2)

任何PRNG,例如Mersenne Twister(因此函数名称中的“mt”)并非真正随机。但对于大多数用途来说,它是随机的。如果您需要真正的随机,那么您应该使用操作系统的随机性设施。

答案 1 :(得分:2)

某些功能专门用于处理加密级别的随机性。

openssl_random_pseudo_bytes是一个很好的(显然需要openssl lib)。您可以使用它来生成具有强随机性的密码。

MT使用的

mt_rand(Mersenne Twister)被认为是PRNG(伪随机数生成器),而openssl_random_pseudo_bytes将尝试使用CSPRNG(加密安全PRNG)。

此函数会生成字节,您可以轻松base64_decode使用base64 character set获取密码。

这一切真的很重要吗?除非你是Facebook或银行,否则可能不是。 mt_rand可能已经足够好了。如果您感兴趣,这确实可以帮助您了解有关加密的更多信息。

答案 2 :(得分:0)

正如其他人所指出的那样,“真正的&#39;随机不存在于计算机中。如果比特确实是随机的,那实际上是非常灾难性的。

话虽如此,对于大多数随机字符串生成器,您可能需要一些模拟均匀分布的采样,因此每个结果(理论上)同样可能。不同的PRNG模拟具有不同成功程度的分布,通常以速度的形式进行权衡。

假设你对mt_rand感到满意(我不知道有什么理由)和标准的可打印ascii字符集,一个简单的方法产生随机字符串,每个字符串在完整的可打印ascii集中具有相同的可能字符这样:

function create_random_string($len) {

    $string = '';

    for ($j = 0; $j < $len; $j++) {
        $string = $string . chr(mt_rand(33,126)); 
    }

    return $string;

}

这是兰特(33,126)的表达。它返回一个可通过chr翻译成可打印的ascii字符集的十进制数,如下所示:http://www.ascii-code.com/

根据兰特函数,每个角色都具有相同的可能性,使其成为随机的&#39;尽可能使用最广泛的可打印字符集(同样,假设您将应用程序限制为ascii字符集)。