如果您需要在任何 PC 上使用它,则需要一个在计算机上运行相同的随机数生成器。我从Random Number Generation Wikipedia 页面查找了一个可能适合您的伪随机数生成器,并将其放入一个类中,以便您对其进行播种。
我不知道你需要什么,但这可能适合你的需要。它独立于系统配置:
function shuffleIt($array, $seed)
{
$mwc = new mwc($seed);
$order = array();
$count = count($array);
while($count--)
$order[] = $mwc->random()
;
array_multisort($order, $array);
return $array;
}
/**
* Multiply-with-carry RNG
*
* method invented by George Marsaglia
*/
class mwc
{
private static $def_m_w = 1712; /* must not be zero */
private static $def_m_z = 23; /* must not be zero */
private $m_w, $m_z;
public function __construct($seed = NULL)
{
$this->m_w = self::$def_m_w;
$this->m_z = self::$def_m_z;
if (NULL !== $seed)
$this->seed($seed);
}
public function seed($seed)
{
$seed = (int) $seed;
if (!$seed) throw new InvalidArgumentException('Must not be zero.');
$this->m_z = $seed;
$this->random();
}
public function random()
{
$this->m_z = 36969 * ($this->m_z & 65535) + ($this->m_z >> 16);
$this->m_w = 18000 * ($this->m_w & 65535) + ($this->m_w >> 16);
return ($this->m_z << 16) + $this->m_w; /* 32-bit result */
}
}
注意:这可能在 32/64 位系统之间表现不同,尤其是 PHP 在 windows 和 unix 之间的整数和溢出方面有所不同。您可能希望 PHP 中 32 位整数的有符号最小值偏移,而不是现在的 0,以便将实现切换为gmp或仅将大小减小一位。
荷兰 ekke 报告的 32 位使用示例
$shuffle = new GeorgeShuffle();
$seed = $shuffle->seed();
$a = array('A', 'B', 'C', 'D', 'E', 'F', 'G');
$shuffle->reOrder($a);
var_dump($a);
$shuffle->seed($seed);
$shuffle->reOrder($a);
var_dump($a);
/**
* Array shuffle class using
* the multiply-with-carry method
* invented by George Marsaglia
*/
class GeorgeShuffle
{
private static $def_m_w = 1959; /* must not be zero */
private static $def_m_z = 2006; /* must not be zero */
private $m_w, $m_z;
const maxint = 2147483647;
public function __construct($seed = null)
{
$this->m_w = self::$def_m_w;
$this->m_z = self::$def_m_z;
if ($seed) $this->seed($seed);
}
public function reOrder(&$array, $seed = null)
{
if (!empty($seed)) $this->seed($seed);
$a = array();
for ($i = 0, $j = count($array); $i < $j; $i++) {
$a[$i] = $this->random();
}
array_multisort($a, $array);
//- to return a copy, remove the &
return $array;
}
public function seed($seed = false)
{
if (is_string($seed)) $seed = hexdec($seed);
if (empty($seed)) $seed = round(mt_rand(1, self::maxint));
$this->m_z = $seed;
$this->random();
//- return the seed used in hex (8 chars) for reproducing
return str_pad(dechex($seed), 8, '0', STR_PAD_LEFT);
}
public function random()
{
$this->m_z = 36969 * (($this->m_z And 65535) + ($this->m_z >> 16));
$this->m_w = 18000 * (($this->m_w And 65535) + ($this->m_w >> 16));
return ($this->m_z << 16) + $this->m_w; /* 32-bit signed result */
}
}