str_shuffle和随机性(str_shuffle and randomness)

2019-07-17 16:17发布

前阵子我写了一个随机串生成器,其构建使用个字符mt_rand()中的字符串,直至达到所希望的长度的字符串。

public function getPassword ()
{
    if ($this -> password == '')
    {
        $pw             = '';
        $charListEnd    = strlen (static::CHARLIST) - 1;
        for ($loops = mt_rand ($this -> min, $this -> max); $loops > 0; $loops--)
        {
            $pw .= substr (static::CHARLIST, mt_rand (0, $charListEnd), 1);
        }
        $this -> password   = $pw;
    }
    return $this -> password;
}

(CHARLIST为含有字符的池的密码一类恒定。$ min和$最大是长度约束上)

如今,研究其他的东西时,我完全是偶然发现下面的代码:

function generateRandomString ($length = 10) {    
    return substr(str_shuffle ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length);
}

这实现了几乎我的循环mt_rand在一行()的代码相同的效果。 我真的很喜欢它那简单的理由,更少的代码始终是一件好事。 :)

但是,当我在PHP手册抬头str_shuffle它的文档是相当轻。 有一件事我真的很热衷于学习它用什么算法随机性? 本手册中没有提到什么样的随机化是为了获得洗牌后的字符串。 如果使用兰特(),而不是mt_rand(),然后坚持到我目前的解决方案可能是毕竟更好。

所以基本上我想知道如何str_shuffle会随机的字符串。 难道使用RAND()或mt_rand()? 我用我的随机字符串函数生成的密码,所以随机性的品质很重要。

更新 :正如已经指出的那样,str_shuffle方法并不等同于我已经使用并会随机的代码由于剩余一样的输入字符串的字符,仅与它们的顺序改变。 不过我还是好奇的str_shuffle功能如何随机化的输入字符串。

Answer 1:

一个更好的解决办法是mt_rand它采用梅森倍捻机这好过得多。

正如已经指出的那样,str_shuffle方法并不等同于我已经使用并会随机的代码由于剩余一样的输入字符串的字符,仅与它们的顺序改变。 不过我还是好奇的str_shuffle功能如何随机化的输入字符串。

为了使输出等于让刚刚用0,1 ,并期待在每个功能的可视化表示

简单的测试代码

header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512) or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for($y = 0; $y < 512; $y ++) {
    for($x = 0; $x < 512; $x ++) {
        if (testMTRand()) { //change each function here 
            imagesetpixel($im, $x, $y, $white);
        }
    }
}
imagepng($im);
imagedestroy($im);

function testMTRand() {
    return mt_rand(0, 1);
}

function testRand() {
    return rand(0, 1);
}

function testShuffle() {
    return substr(str_shuffle("01"), 0, 1);
}

输出testRand()

输出testShuffle()

输出testMTRand()

所以基本上我想知道如何str_shuffle会随机的字符串。 难道使用RAND()或mt_rand()? 我用我的随机字符串函数生成的密码,所以随机性的品质很重要。

你可以清楚地看到, str_shuffle产生几乎相同的输出rand ...



Answer 2:

请注意,如果您的应用程序真正关注的安全不应该使用这种方法。 梅森倍捻机是不加密的安全。 一个PRNG可以产生,其统计似乎是随机的,但还是很容易打破值。



Answer 3:

还没加密的安全,但在这里是一种使用str_shuffle()同时允许字符重复,从而提高了复杂性...

generate_password($length = 8, $strength = 3) {
    if ($length < 6) $length = 6;
    if ($length > 32) $length = 32;
    // Excludes [0,O,o,1,I,i,L,l,1] on purpose for readability
    $chars = 'abcdefghjkmnpqrstuvwxyz';
    if ($strength >= 2) $chars .= '23456789';
    if ($strength >= 3) $chars .= strtoupper($lower);
    if ($strength >= 4) $chars .= '!@#$%&?';
    return substr(str_shuffle(str_repeat($chars, $length)), 0, $length);
}

$chars重复$length的时间被打乱的字符串之前,使这个比仅洗牌单个事件更好一点。

我们只有在不存储敏感信息系统使用;)



文章来源: str_shuffle and randomness