我需要根据种子编号对数组进行混洗,以便在需要时可以进行相同的随机播放。
例如:
1. print_r( shuffleIt( $array, 2 ) );
2. print_r( shuffleIt( $array, 6 ) );
3. print_r( shuffleIt( $array, 2 ) );
我发现这个功能谷歌搜索:
function entropy( $array, $sort_seed ) {
mt_srand( $sort_seed );
$order = array_map( create_function( '$val', 'return mt_rand( );' ), range( 1, count( $array ) ) );
array_multisort( $order, $array );
return $array;
}
它在我的电脑上使用php-cli工作正常,我总是为我使用的每个不同的sort_seed获得相同的数组,但是当我将它上传到服务器时,即使我使用相同的sort_seed,我每次都会获得不同的数组
使用相同的sort_seed时,如何始终获得相同的混洗数组?
顺便说一句。我需要保存密钥或对多维数组进行排序,以便将密钥存储在那里。
答案 0 :(得分:2)
如果你需要在任何电脑上使用它,你需要一个随机数发生器,它可以在计算机上运行。我从Random Number Generation Wikipedia page查找了一个可能适合你的伪随机数生成器,并将它放入一个类中,这样你就可以播种它。
我不知道你需要什么,但这可能适合你的需要。它独立于系统配置:
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位整数的有符号最小值进行偏移,而不是现在的偏移,将实现切换为gmp或仅将大小减小一位。
用法示例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 */
}
}
答案 1 :(得分:1)
您是否偶然托管了Suhosin安全扩展程序?显然,它有几个指令阻止脚本设置种子:
suhosin.srand.ignore = On
suhosin.mt_srand.ignore = On
进一步阅读:
以下是测试这是否是问题的快速方法:
<?php
mt_srand(33);
var_dump(mt_rand(1, 10000));
mt_srand(33);
var_dump(mt_rand(1, 10000));
mt_srand(33);
var_dump(mt_rand(1, 10000));