Search code examples
powershellunique-id

PowerShell Script to Generate Large Volume (in millions) 'n' digits Unique Number


I am trying to write a powershell script to generate about 9 million unique number. Is there any efficient way to do that?

As of now My script is, But it is generating duplicate values

$start = [long] $startNumber
$end = [long] $endNumber
$random = New-Object System.Random
$number = @()

while ($start -lt $end){

$customerObject = new-object PSObject

    $randomnumber = $random.Next(100000000,999999999)
    while ($number -contains $randomnumber) {
            $randomnumber = $random.Next(100000000,999999999)
     }
    $number += $randomnumber
    [long] $uniqueId = 2000000000 +[long] $randomnumber;



$customerObject | add-member -membertype NoteProperty -name CUSTOMERID -Value $uniqueId 

$start++
$resultsarray += $customerObject

}


Solution

  • I would maintain a separate HashSet<int> to keep track of the distinct values already generated.

    A HashSet doesn't preserve insertion order but is crazy-fast to perform lookups against, unlike a regular array in which lookup-performance will become quite sluggish after a while (which you've probably already seen yourself).

    Secondly, avoid += at any cost. PowerShell arrays resize themselves by recreating and copying the underlying array to a slighter larger array. This constant resizing is going to hurt performance as well.

    You can rely on the pipeline alone by simply "dropping" your variables on a line and assign the output from the entire while loop to a variable that will then contain your random(ly ordered) sequence:

    $random = New-Object System.Random
    $set = New-Object 'System.Collections.Generic.HashSet[int]'
    
    $limit = $endNumber - $startNumber
    
    $sequence = while($set.Count -lt $limit)
    {
        # Generate random number
        $n = $random.Next(100000000,999999999)
    
        # Re-generate until a distinct value is produced
        while($set.Contains($n)){
            $n = $random.Next(100000000,999999999)
        }
    
        # Add value to set
        [void]$set.Add($n)
    
        # Let value "bubble up" to the variable
        $n
    }