Powershell Get-Random
cmdlet的文档表明种子是系统滴答计数但是,如果执行了以下测试,则$rand1
的值不会复制到for()
的输出中1}}循环似乎与TickCount
无关。为什么会这样?
# generate a random int32 - should automatically use the tickcount as seed?
$tick1 = ([Environment]::TickCount)
$rand1 = Get-Random
Write-Host $rand1
$tick2 = ([Environment]::TickCount)
# generate seeded randoms with all possible values used to generate $rand1
for ($i = $tick1; $i -le $tick2; $i++) {
$rand2 = Get-Random -SetSeed $i
Write-Host $rand2
}
答案 0 :(得分:3)
Get-Random
不一定在您使用它时直接播种(当然不是每次使用它时),它可以是在进程启动时,也可以是在会话中首次使用它时。 PRNG通常不应该播种多次。
此外,正如Mathias在评论中指出的那样,它不一定直接使用Environment.TickCount
的值。您可以使用ILSpy查看相关程序集的来源,以了解它是如何完成的。我不会那样做,因为我是开源PowerShell实现的贡献者。
答案 1 :(得分:0)
所以,我今天对此感到很好奇,因为PowerShell是开源的,我认为我只是去看看source code ...
Get-Random不使用[Environment]::TickCount
作为种子。实际上,只有当您手动指定种子时,它才不使用[System.Security.Cryptography.RandomNumberGenerator]::Create()
。
它有2个构造函数...
internal class PolymorphicRandomNumberGenerator
{
public PolymorphicRandomNumberGenerator()
{
_cryptographicGenerator = RandomNumberGenerator.Create();
_pseudoGenerator = null;
}
internal PolymorphicRandomNumberGenerator(int seed)
{
_cryptographicGenerator = null;
_pseudoGenerator = new Random(seed);
}
...
仅当SetSeed在Begin进程中具有值时,它才使用种子调用构造函数:
/// <summary>
/// This method implements the BeginProcessing method for get-random command.
/// </summary>
protected override void BeginProcessing()
{
if (SetSeed.HasValue)
{
Generator = new PolymorphicRandomNumberGenerator(SetSeed.Value);
}
...
这将使用_pseudoGenerator
设置System.Random
否则,它只会在没有种子的情况下调用公共构造函数...使用_cryptographicGenerator
设置System.Security.Cryptography.RandomNumberGenerator