2012-02-28 6 views
4

私は一貫した結果を持つ配列をランダム化する必要があるPHPスクリプトを持っているので、ユーザに最初のいくつかのアイテムを提示することができ、望むのであれば同じシャッフルセットからさらに多くの結果を引き出すことができます。suhosin.mt_srand.ignoreがPHPで配列を一貫してシャッフルするのを回避するには?

は私が現在使用していることは、この(私は信じているフィッシャーイエーツアルゴリズムに基づいて)です:私のローカルインストールで正常に動作します

function shuffle(&$array, $seed) 
{ 
    mt_srand($seed); 
    for ($a=count($array)-1; $a>0; $a--) { 
     $b = mt_rand(0, $a); 
     $temp = $array[$a]; 
     $array[$a] = $array[$b]; 
     $array[$b] = $temp; 
    } 
} 

が、それはSuhosinがインストールされている上で実行する必要があるサーバー、これはmt_srandをオーバーライドします。つまり、シードは無視され、配列はランダムにシャッフルされ、ユーザーは重複した結果を取得します。私はGoogleで見つけた

すべては私が(後者はしかし関連性があるかどうかわからないとsuhosin.srand.ignore、)ので、私は入れsuhosin.mt_srand.ignoreを無効にする必要が示唆して.htaccessファイルに次の

php_flag suhosin.mt_srand.ignore Off 
php_flag suhosin.srand.ignore Off 

私はこのサーバ上でphp.iniにアクセスすることができませんので、AFAIKだけがそれを行うことができます。問題はそれは効果がありません - phpinfo()は両方の設定をOnとして表示しますが、.htaccessを使って他のSuhosin設定を変更することはできます。

私が探しているのは、実際にsuhosin.mt_srand.ignore(またはそれが動作しない理由)を無効にする方法か、PHP内から乱数ジェネレータをシードする回避策です。それとも、自分で別のRNGを実装する必要がありますか?

ご協力いただければ幸いです。ありがとう!私はちょうど:)行っているようにあなたが非常に簡単に独自のランダム関数を作成することができますいくつかの基本的な数学といくつかのトリックを使用して

+0

キャッシュのどこかで、結果の配列、... – KingCrunch

+0

らしいです。その性質上、多くのシャッフルを行う必要があります(検索に基づいているため、ユーザーが再配置を検索するたびに)、各シャッフルはおそらく最大2〜3回しか使用されません。それはサイトで頻繁に使われている部分なので、異なるユーザーのために異なる配列のシャッフルされたバージョンをキャッシュしています。多くの場合同じ結果が別々にシャッフルされています各アレイとすべてのアレイをどのくらいの期間保持するかということです。 – alexz

+0

本当に必要なのは、すべてのユーザーが_完全に別のバージョンを表示する必要があるか、複数のユーザーに対して1つのシャッフルセットを使用できないことですか? – KingCrunch

答えて

2

申し訳ありませんが、私はそれをクリーンアップしていません。これまでの種子と再播種する必要を防ぐことができるので、クラスではるかに良いでしょう。静的変数を使用しないでください。これは、一度に1つのシードのみを使用するように制限するためです(または、手動でシードを手動で追跡する)。 OOPはそれを解決するだろう。下記の機能で好きなことをやってください。しかし、書き直したら教えてください。それはしかし、かなり簡単であるべき何かのために多くの問題を紹介したいようにそれにすべての要求を再作成していない、このことができます

/** 
* returns a decimal between 0 and max_number, requires seeding every time and will ALWAYS return the same decimal for the same seed 
* @copyright scott thompson, all rights reserved 
* @license MIT (do what you like with this) 
* @param string $seed 
* @param int $max_number=100 adjust the maximum number range 
*/ 
function random_number($seed, $max_number = 100) { 

    //make sure there won't be any deadspace where random numbers will never fill 
    if ($max_number > 0xFFFFFF) { 
     trigger_error("Max random number was to high. Maximum number of " . 0xFFFFFF . " allowed. Defaulting to maximum number.", E_USER_WARNING); 
     $max_number = 0xFFFFFF; 
    } 

    //hash the seed to ensure enough random(ish) characters each time 
    $hash = sha1($seed); 

    //use the first x characters, and convert from hex to base 10 (this is where the random number is obtain) 
    $rand = base_convert(substr($hash, 0, 6), 16, 10); 

    //as a decimal percentage (ensures between 0 and max number) 
    return $rand/0xFFFFFF * $max_number ; 

} 

$seed = 'hello'; 
print ($seed = random_number($seed)) . '<br />'; //66.779748605475 
print ($seed = random_number($seed)) . '<br />'; //3.5753311857779 
print ($seed = random_number($seed)) . '<br />'; //13.994396567011 
print ($seed = random_number($seed)) . '<br />'; //70.344917198713 
print ($seed = random_number($seed)) . '<br />'; //4.5583250855401 

希望、スコット

+0

ありがとう、それは私の2番目のアプローチだったことを認めなければならない。>最初にハッシュの各文字のord()値を使ってみたが、それは私には見えなかった0.5から0.6までの数字しか与えなかった!だから、ちょうど16進値であるように起こるハッシュの前を切り取って別のアプローチを取ってしまうことになりました...それは私が思っていたよりもうまくいっていました。 – VBAssassin

関連する問題