How Random Is PHP's Shuffle Function

How random is PHP's shuffle function?

shuffle() function is based on the same generator as rand(), which is the system generator based on linear congruential algorithm. This is a fast generator, but with more or less randomness. Since PHP 4.2.0, the random generator is seeded automatically, but you can use srand() function to seed it if you want.

mtrand() is based on Mersenne Twister algorithm, which is one of the best pseudo-random algorithms available. To shuffle an array using that generator, you'd need to write you own shuffle function. You can look for example at Fisher-Yates algorithm. Writing you own shuffle function will yield to better randomness, but will be slower than the builtin shuffle function.

How to use random () function to shuffle array in PHP

The built-in shuffle() doesn't handle associative arrays very well, so you'd need to shuffle the array keys and then reconstitute the array again.

I'm using the Fisher-Yates-Knuth algorithm to perform the shuffling, which is really the crux of the solution.

function myshuffle($arr)
{
// extract the array keys
$keys = [];
foreach ($arr as $key => $value) {
$keys[] = $key;
}

// shuffle the keys
for ($i = count($keys) - 1; $i >= 1; --$i) {
$r = mt_rand(0, $i);
if ($r != $i) {
$tmp = $keys[$i];
$keys[$i] = $keys[$r];
$keys[$r] = $tmp;
}
}

// reconstitute
$result = [];
foreach ($keys as $key) {
$result[$key] = $arr[$key];
}

return $result;
}

What is the best way to randomize an array's order in PHP without using the shuffle() function?

You could use the Fisher-Yates shuffle.

PHP shuffle vs rand - which produces better randomness

Both use the same PRNG so their randomness is equally good/bad. Obviously a plain rand(1,6) is faster since it's just the math and not both the math and the array stuff. Besides that, you'd use array_rand() if you wanted a random element from an array.

PHP also has the mersenne twister (mt_rand()) which is "better" but unsuitable for cryptography (probably not relevant in your case).

If you need true randomness you could consider reading from /dev/random - but that read may block if there's no randomness available. You could also use a hardware device that gives you even better randomness based on some physical effect.

How to shuffle list in PHP

print_r function display data as they are. So it print array when you give it array. You need to implode your array into string:

echo  implode('',shuffle_assoc($arr));

edit:

or just

echo  implode('',shuffle($arr));

PHP difference between shuffle and array_rand

When called on an array, shuffle randomizes the order of all elements of that array.

For example, the following portion of code :

$arr = array(1, 2, 3, 4, 5);
shuffle($arr);
var_dump($arr);

Could give this output :

array
0 => int 3
1 => int 1
2 => int 5
3 => int 4
4 => int 2

The whole array itself gets modified.


When called on an array, array_rand returns one or more keys from that array, randomly selected.

For example, the following portion of code :

$arr = array(1, 2, 3, 4, 5);
$randomly_selected = array_rand($arr, 3);
var_dump($randomly_selected);

Could give tis kind of output :

array
0 => int 0
1 => int 2
2 => int 3

A sub-array of the initial array is returned -- and the initial array is not modified.

The algorithm used by PHP shuffle function

What exactly constitutes "not good results"?

The Fisher-Yates shuffle will produce all permutations with equal probability, but only if you generate your random numbers correctly. There's three issues to be aware of here. First, you need a good pseudorandom number generator. The C standard library rand usually is not a good PRNG (though it depends on your C library implementation). If you're on a POSIX platform, consider using lrand48 instead. Your system may have other RNGs. If you don't have anything on your platform, a pretty good RNG in very little code is G. Marsaglias KISS generator - you can find the code here. Second, if you still decide to use rand, be aware that it will generate random numbers between 0 and RAND_MAX. For lots of implementations, RAND_MAX is only 32767, so the usual rand() % count will have a very obvious and bad bias if count is larger than 32768. Third, rand() % count (or lrand48() % count or anything similar) is actually a bad idea too, because it too introduces a bias. If count isn't a power of 2, some numbers will have a higher probability than others. Also, in a lot of generators, the low-order bits are a lot less random than the high-order bits. You can try to work around this by using (long long) rand() * count / RAND_MAX or something similar, but really you're better of using a good RNG instead.

The proper way to generate unbiased random numbers between 0 (inclusive) and k (exclusive) is this: First, get a proper PRNG that gives you a large-enough random number (say 32 random bits). Then reduce to the next power of 2 larger than k. Finally, if the value is greater than or equal to k, try again. This is a completely unbiased method, and will give results that are as good as your PRNG can make them. The code looks something like this:

static unsigned int random(unsigned int k)
{
// You can get rid of this loop using bit tricks, but I keep it for clarity
unsigned int n, nextpow2 = 1;
while (nextpow2 < k)
nextpow2 *= 2;

do {
n = random32() & (nextpow2 - 1); // random32 is your 32-bit RNG
} while (n >= k);

return n;
}

shuffle order of images in php

There is a function for that, shuffle():

$images = array
(
'/images/carousel-1.jpg',
'/images/carousel-2.jpg',
'/images/carousel-3.jpg',
'/images/carousel-4.jpg',
);

shuffle($images); // the magic

foreach ($images as $image)
{
echo '<div class="image-entry">';
echo "\t" . '<img src="' . $image . '" />';
echo '</div>';
}

PHP Random Shuffle Array Maintaining Key = Value

The first user post under the shuffle documentation:

Shuffle associative and
non-associative array while preserving
key, value pairs. Also returns the
shuffled array instead of shuffling it
in place.

function shuffle_assoc($list) { 
if (!is_array($list)) return $list;

$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $key) {
$random[$key] = $list[$key];
}
return $random;
}

Test case:

$arr = array();
$arr[] = array('id' => 5, 'foo' => 'hello');
$arr[] = array('id' => 7, 'foo' => 'byebye');
$arr[] = array('id' => 9, 'foo' => 'foo');
print_r(shuffle_assoc($arr));
print_r(shuffle_assoc($arr));
print_r(shuffle_assoc($arr));


Related Topics



Leave a reply



Submit