我正在使用下面的函数为文件名生成随机字符串。我在Unix机器上没有遇到任何问题,但我在Windows上有很多重复。我刚做了一个测试并生成了100.000个字符串,结果是每个字符串出现227(??)次。有人能解释一下吗?即使使用rand()
我也有重复项,但srand()
似乎有效。
function generateRandomString($length = 6)
{
$rows = array();
array_push($rows, range('A', 'Z'));
array_push($rows, range('a', 'z'));
array_push($rows, range(0, 9));
$signs = array();
foreach ($rows as $row) {
$signs = array_merge($signs, $row);
}
shuffle($signs);
shuffle($signs);
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= $signs[array_rand($signs, 1)];
}
return $password;
}
答案 0 :(得分:0)
嗯,首先,Windows文件名不区分大小写,因此您应该只在源数组中使用小写或大写字符,而不是两者都使用。
其余部分基本上取决于您正在使用的PHP处理器的实际实现,而不是Windows vs. * nix。也许它们依赖于定时器分辨率并且不保持内部状态 - 由于通常定时器分辨率大约为15ms,这并不是很糟糕。无论如何,它很可能是PHP实现的问题,而不是Windows本身,因为C#中的这段代码很好地说明了:
Random rnd = new Random();
byte[] buf = new byte[10 * 100000];
rnd.NextBytes(buf);
buf
.Select((val, idx) => new { Index = idx, Value = val })
.ToLookup(i => i.Index / 10)
.Select(i => string.Join(string.Empty,
i.Select(j => j.Value.ToString("X2")).ToArray()))
.GroupBy(i => i)
.Where(i => i.Count() > 1)
.Dump();
这将创建10个20个字符(0
到F
)的随机字符串,并查找重复项。在几百次测试中,我没有发生过一次碰撞。因此,如果您在PHP中使用随机生成器时遇到问题,请查看您正在使用的PHP的特定实现,而不是指责Windows :)
有趣的是,你的代码如何进行一些随机性传递(将$signs
数组混洗两次,然后从中随机挑选?)。这样做最有可能减少数据的随机性,而不是增加它。似乎是一种愚蠢的尝试,隐藏密码生成机制背后隐藏的层次(然后开源......呃:D)。
至于密码(你的代码似乎表明它的用途是什么),你应该使用加密安全的randoms - 它们更不可预测,更随机,更不容易偏压。