Workaround for suhosin.mt_srand.ignore for sequentially shuffling an array in PHP?

I have a PHP script that needs to randomize an array with consistent results so that it can present the first few elements to the user, and then they can extract more results from the same shuffled set if they want.

I am currently using this (based on the Fisher Yates algorithm, which I consider):

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

Which works well on my local installation, but Suhosin was installed on the server it should be running on, which overrides mt_srand, which means that the seed is ignored, the array is just randomly shuffled, and the user gets duplicate results.

Everything I found on Google suggests that I need to disable suhosin.mt_srand.ignore (and suhosin.srand.ignore, not sure if the latter is relevant), so I put the following in .htaccess:

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

I do not have access to php.ini on this server, so AFAIK is the only way to do this. The problem is that it has no effect - phpinfo () still shows both settings as On, while I can change other Suhosin settings using .htaccess without any problems.

So, I believe that what I'm looking for is either a way to disable suhosin.mt_srand.ignore (or the reason it doesn't work), or a workaround for generating a random number generator from PHP. Or do I just need to implement another RNG?

Any help would be greatly appreciated. Thanks!

+4
source share
1 answer

Using some basic mathematical data and a few tricks, you can easily create your OWN random function, as I just did :)

It is a pity that I did not clean it. It would be much better in class, as you could prevent the need to re-sow it with the previous seed. Do not use a static variable as it limits you to using only one seed at a time (or manually tracking the seeds yourself). OOP will solve this. Do what you like using the function below, but let me know if you are rewriting it.

 /** * 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 

Hope this helps, scott

+2
source

Source: https://habr.com/ru/post/1398812/


All Articles