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; 
    } 
} 

하지만 수호신가 설치되어 실행하는 데 필요한 서버, seed가 무시된다는 것을 의미하는 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

모든 사용자가 _completely_ 다른 버전을보아야한다는 요구 사항입니까, 아니면 여러 사용자에게 하나의 셔플 세트 만 사용할 수 있습니까? – 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

고마워, 내 두 번째 접근이었다 인정해야합니다. <처음 해시에서 각 문자의 ord() 값을 사용하여 시도했지만, 0.5에서 0.6 사이의 숫자 만 받았다.그래서 해쉬의 앞부분을 잘라내어 16 진수 값이되는 다른 접근 방식을 취한 것입니다 ... 실제로 효과가 있었고 실제로 생각했던 것보다 잘 작동했습니다. – VBAssassin