0

擬似ランダム文字列を生成するコードを作成しました。ユーザーのマウスの動きからエントロピーを収集することで、ランダム性を改善しようとしました。

これが私のコードです:

// As described in the PHP documentation
function make_seed() {
    list($usec, $sec) = explode(' ', microtime());
    return (float) $sec + ((float) $usec * 100000);
}

function rand_string($entropy, $length, $chars) {
    mt_srand($entropy . make_seed()); // Here is the important line
    $return = '';
    $charlen = strlen($chars);
    for ($i=0;$i<$length;$i++) {
        $rand = mt_rand(0, $charlen) - 1;
        $return .= substr($chars, $rand, 1);
    }
    return $return;
}

$entropy = '18421828841384386426948169412548'; // Mouse movements, changes everytime
echo rand_string($entropy, 20, 'abcdefghijklmnopqrstuvwxz');

関数を数回実行しました。一部の値は非常に頻繁に表示されるため、これは非常に弱い機能です。理由がわかりません。mt_srand のパラメータに制限はありますか? 数字である必要がありますか?

編集: mt_srand() シードは INT でなければなりません。

4

2 に答える 2

1

mt_srand() は符号なし 32 ビット整数を取り、メルセンヌ ツイスターを初期化します。
http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/rand.c?revision=321634&view=markup :

194     /* {{{ php_mt_srand
195     */
196     PHPAPI void php_mt_srand(php_uint32 seed TSRMLS_DC)
197     {
198     /* Seed the generator with a simple uint32 */
199     php_mt_initialize(seed, BG(state));
200     php_mt_reload(TSRMLS_C);
201     
202     /* Seed only once */
203     BG(mt_rand_is_seeded) = 1;
204     }
205     /* }}} */

エントロピー/ランダムビットを収集するために、基礎となるシステムの手段を検索することをお勧めします。
これは、* nix マシンではrngd + /dev/randomであり、Windows ではCryptGenRandomまたは (到達するのは簡単ですが遅い) CAPICOM Utilities.GetRandom()になります。

必要に応じて、mcrypt_create_iv()も良い選択です (おそらく、iv から「読み取り可能な」文字列を作成するものと組み合わせて)。

于 2013-02-28T15:34:46.233 に答える
0

PHP の rand() 関数を使用せずに、独自のランダム文字列ジェネレーターを作成しました。

function rs($length,$chars)
{
    $hex = sha1(microtime()); //contains hexadecimal string
    $return = '';
    $seedLen = strlen($chars); //length of the source characters string
    $posLen  = strlen($hex); //length of the hex string
    for($i=0;$i<$length;$i++){
        $idx_hex = $i % ($posLen-1); //make sure the address is in the hex string (if $i is too big)
        $pos = hexdec($hex[$idx_hex].$hex[$idx_hex+1]);
        $return .= $chars[$pos % $seedLen];
    }
    return $return;
}

仕組みは次のとおりです: 現在時刻の sha1 ハッシュ (06009da3e0d26f8569b65cb50a774bb6b431a777 のような文字列) を生成し、ハッシュから一度に 2 つの値を取得し、それを $chars 文字列内の文字の 16 進数の「アドレス」として使用します。つまり、この例では、$chars 文字列が "abcdefghijklmnopqrstuvwxyz" の場合、"random" 文字列の最初の文字は "g" (chars 文字列のインデックス 06 の文字) になります。制限: (1) $chars 文字列から最初の 256 文字のみが使用されます (256 文字より長い場合) (2) モジュロ演算子のため、この関数は mt_rand() よりも遅くなります。

編集: mt_rand() はモジュロ演算子も使用するため、速度はこの関数と同じオーダーになる可能性があります。私は比較を実行しませんでした。

于 2013-02-28T15:30:23.020 に答える