Powershell Get-Random cmdlet的默认种子是什么

时间:2015-12-17 09:55:09

标签: powershell random

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
}

2 个答案:

答案 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

相关问题