どのPCでも必要な場合は、コンピューター間で同じように機能する乱数ジェネレーターが必要です。乱数生成ウィキペディアのページから、自分に適している可能性のある疑似乱数ジェネレーターを1つ検索し、それをクラスに入れてシードできるようにしました。
何が必要かわかりませんが、これはあなたのニーズにぴったりかもしれません。システム構成とは無関係です。
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ビットシステム間で異なる動作をする可能性があります。特に、ここでは整数とWindowsとUNIX間のオーバーフローでPHPが異なるためです。実装をgmpに切り替えるか、サイズを1ビット減らすために、現在の0ではなくPHPの32ビット整数の符号付き最小値でオフセットする必要がある場合があります。
使用例32ビットはオランダのekkeによって動作すると報告されています
$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 */
}
}