user5690322
user5690322

Reputation: 41

What is the default seed for Powershell Get-Random cmdlet

The documentation for the Powershell Get-Random cmdlet suggests that the seed is the system tick count but, if the following test is performed, the value of $rand1 is not replicated in the output of the for() loop and so appears to be independent of TickCount. Why is this so?

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

Upvotes: 4

Views: 3082

Answers (2)

MysticRyuujin
MysticRyuujin

Reputation: 25

So, I was curious about this today and now that PowerShell is open source I thought I'd just go look at the source code...

Get-Random does not use [Environment]::TickCount as the seed. In fact the only time it doesn't use [System.Security.Cryptography.RandomNumberGenerator]::Create() is when you manually specify a seed.

It has 2 constructors...

internal class PolymorphicRandomNumberGenerator
{
    public PolymorphicRandomNumberGenerator()
    {
        _cryptographicGenerator = RandomNumberGenerator.Create();
        _pseudoGenerator = null;
    }

    internal PolymorphicRandomNumberGenerator(int seed)
    {
        _cryptographicGenerator = null;
        _pseudoGenerator = new Random(seed);
    }
    ...

It only calls the constructor with a seed if SetSeed has a value in the Begin process:

/// <summary>
/// This method implements the BeginProcessing method for get-random command.
/// </summary>
protected override void BeginProcessing()
{
    if (SetSeed.HasValue)
    {
        Generator = new PolymorphicRandomNumberGenerator(SetSeed.Value);
    }
    ... 

That would set _pseudoGenerator using System.Random

Otherwise it only ever calls the public constructor without a seed...which sets _cryptographicGenerator using System.Security.Cryptography.RandomNumberGenerator

Upvotes: 2

Joey
Joey

Reputation: 354576

Get-Random isn't necessarily seeded directly when you use it (certainly not every time you use it), it could be either at process startup, or when you first use it in a session. PRNGs shouldn't be seeded more than once, usually.

Also, as Mathias notes in a comment, it doesn't necessarily use the value of Environment.TickCount directly. You could use ILSpy to look at the source of the relevant assembly to find out how exactly it's done. I won't do that for you since I'm a contributor to an open-source PowerShell implementation.

Upvotes: 3

Related Questions