16

しばらく前に、文字列内の 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 と $max は長さの制約です)

今日、まったく別のことを調べていると、次のコードに出くわしました。

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

これは、私の mt_rand() ベースのコードを 1 行でループするのとほぼ同じ効果を達成します。コードの行数が少ないことは常に良いことです。:)

しかし、PHP のマニュアルで str_shuffle を調べたところ、そのドキュメントは非常に簡単でした。私が本当に学びたかったことの 1 つは、ランダム性にどのアルゴリズムを使用するかということでした。マニュアルには、シャッフルされた文字列を取得するためにどのようなランダム化が行われるかについては言及されていません。mt_rand() の代わりに rand() を使用している場合は、現在のソリューションに固執する方が良いかもしれません。

基本的に、 str_shuffle が文字列をランダム化する方法を知りたいです。rand() または mt_rand() を使用していますか? ランダム文字列関数を使用してパスワードを生成しているため、ランダム性の質が重要です。

更新:指摘されているように、str_shuffle メソッドは、私が既に使用しているコードと同等ではなく、文字列の文字が入力と同じままであるため、順序が変更されているだけでランダム性が低くなります。ただし、str_shuffle 関数が入力文字列をランダム化する方法については、まだ興味があります。

4

3 に答える 3

35

より良い解決策は、Mersenne Twistermt_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ます...

于 2012-12-29T08:27:29.440 に答える