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

Powershell Get Random cmdlet的默认种子是什么,powershell,random,Powershell,Random,PowershellGet Randomcmdlet的文档表明种子是系统滴答数,但如果执行以下测试,则$rand1的值不会复制到for()循环的输出中,因此看起来与滴答数无关。为什么会这样 # generate a random int32 - should automatically use the tickcount as seed? $tick1 = ([Environment]::TickCount) $rand1 = Get-Random Write-Host $rand1 $tick

Powershell
Get Random
cmdlet的文档表明种子是系统滴答数,但如果执行以下测试,则
$rand1
的值不会复制到
for()
循环的输出中,因此看起来与
滴答数
无关。为什么会这样

# 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
}

Get Random
不一定在您使用它时直接播种(当然不是每次都使用),它可以是在进程启动时,也可以是在会话中首次使用时。通常情况下,PRNG的播种次数不应超过一次


此外,正如Mathias在评论中指出的,它不一定直接使用
Environment.TickCount
的值。您可以使用ILSpy查看相关程序集的源代码,以了解它是如何完成的。我不会为您这样做,因为我是开源PowerShell实现的贡献者。

所以,我今天对此很好奇,现在PowerShell是开源的,我想我应该去看看

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);
    }
    ... 
//
///此方法实现get random命令的BeginProcessing方法。
/// 
受保护的覆盖void BeginProcessing()
{
if(设定速度值)
{
发电机=新发电机(设定速度值);
}
... 
这将使用
System.Random


否则,它只会调用没有种子的公共构造函数…这将使用
System.Security.Cryptography.RandomNumberGenerator

设置
\u cryptographicGenerator
,设置
\u cryptographicGenerator
值无疑会在将当前滴答计数分配给
$1
和解析之间的时间内增加+执行
Get Random
。此外,帮助文件说明它使用系统时钟来计算种子,而不是种子是系统时钟的值,必要时记录第一点:这就是为什么我收集了之前和之后的勾号计数($tick1和$tick2)然后循环所有可能的值,在生成$rand1时,这些值可以随机获得,所以我认为这是可以解释的?奇怪的是,Get Random只是.net Random函数的一个包装器。我已经测试了该函数,它确实按照预期工作-它确实使用了滴答数。你是对的re在PowerShell cmdlet中肯定有一些额外的功能,但是当使用PowerShell reflector检查它时,我看不出它除了调用和传递.net生成器之外做了什么。它有点模糊。如果打开ILSpy并比较mscorlib中的
Random
类和Microsoft.PowerShell中的
GetRandomCommand
l、 Commands.Utility,您会发现
GetRandomCommand
并没有包装
Random
,而是绕过
RandomNumberGenerator
,初始化它自己的
Random(Environment.TickCount)
初始化,这是您期望从
Random
Altogether获得的,这非常有用Mathias-谢谢,我一直在使用Reflector查看cmdlet,但也刚刚使用ILSpy查看了一下-我看不到RandomNumberGenerator的定义-只是GetRandomCommand似乎正在BeginProcessing()中调用Random功能?