Reputation: 227
I want to generate 10k of unique numbers composed of a sequential number (16 digits) followed by a random numeric string (4 digits). Weapon of choice is Powershell because it's the only tool I have a very limited knowledge of.
Problems encountered:
Get-Random -Minimum 0001 -Maximum 9999
and putting them in a variable. I manage only to obtain 1 random number.How can I combine these 3 commands to obtain a list of semi random numbers as specified above? Or is there simpler way to achieve the same result?
Upvotes: 1
Views: 4162
Reputation: 850
Similar to elegant and accepted iRon's answer here is a way to generate 26 digit serial number that is suitable for SMBIOS or chasis serial number (for example when creating virtual machine):
"{0:####-####-####-####}-{1:####-####-##}" -f (Get-Random -Minimum 1000000000000000 -Maximum 9999999999999999),(Get-Random -Minimum 1000000000 -Maximum 9999999999)
And sample output results like this:
5682-4527-3132-4212-5548-2660-46
6433-6848-9306-5822-1601-7101-98
6986-6609-3112-9326-3662-7689-92
References
Upvotes: 0
Reputation: 437588
iRon's answer provides an elegant solution.
Let me complement it by addressing points 1. and 2. individually:
Re 1.
..
, the range operator supports only [int]
(System.Int32
) (numeric) endpoints (incidentally, the same applies to LINQ's Range
method).
You can use the .ForEach()
array method to work around the problem, as also shown in iRon's answer.
# Returns a collection of [long] (System.Int64) values.
(0..10000).ForEach({ 1400000000000000 + $_ })
Re 2.
PowerShell [Core] now supports a -Count
parameter for Get-Random
that allows you to request a given number of random numbers between the specified bounds.
# PowerShell [Core] only
# Note that there's no point in specifying leading zeros (0001).
# The output will be an array of unformatted [int] (System.Int32) values
$10kRandomNums = Get-Random -Count 10000 -Minimum 1 -Maximum 9999
Note: The -Maximum
value (unlike -Minimum
) is non-inclusive; that is, the highest random number that can be returned is 1 lower, 9998
.
In Windows PowerShell, you'll have to call Get-Random
in a loop:
# Windows PowerShell
$10kRandomNums = foreach ($i in 1..10000) { Get-Random -Minimum 1 -Maximum 9999 }
Calling a cmdlet in a loop is expensive; you can speed things up noticeably by using the System.Random
.NET class directly:
$rnd = [Random]::new()
$10kRandomNums = foreach ($i in 1..10000) { $rnd.Next(1, 9999) }
Upvotes: 1
Reputation: 23663
(0..10000).ForEach{ '14000000000{0:00000}{1:0000}' -f $_, (Get-Random 10000) }
Result:
14000000000000004965
14000000000000010114
14000000000000026382
14000000000000038644
14000000000000045435
14000000000000052051
14000000000000061801
14000000000000077046
14000000000000087791
14000000000000098090
14000000000000102712
....
Explanation:
-f
) to format the string, like '14000000000{0:00000}{1:0000}'
. For details, see composite formatting.[int32]
, just count from 0..1000
with leading zeros up to 5 digits ({0:00000}
) and prefix it with 14000000000
{1:0000}
), place a new random number with leading zeros up to 4 digitsUpvotes: 4
Reputation: 24071
The classic algorithm for creating an unique sequence is to put all the values into an array. Pick a value. Move the last value of the array into the place from where you just picked the value. Then decrease the array's size by one. This creates a copy of the array, so if there are lots of values, be wary of the extra cost that is caused by resizing an array.
An example that shuffles values from 0 to 19 is like so,
$rnd = @()
$arr = 0..19
$tail = $arr.Length-1
do {
$pick = get-random -min 0 -max $tail
$rnd += $arr[$pick]
$arr[$pick] = $arr[$tail]
$tail--
} while($tail -gt 0)
$rnd += $arr[0]
# Uncomment the next statement to print shuffled array
# $rnd -join ', '
Since the value doesn't fit into int32, use int64. To add the shuffled values, a loop works like so,
$big = @()
$seed = [int64]1400000000000000
$rnd | % {
$big += $seed + $_
}
$big
PS C:\> $big
1400000000000015
1400000000000006
1400000000000010
1400000000000017
1400000000000009
1400000000000004
1400000000000005
1400000000000016
1400000000000014
1400000000000003
1400000000000001
1400000000000002
1400000000000013
1400000000000011
1400000000000012
1400000000000019
1400000000000000
1400000000000007
1400000000000008
1400000000000018
Upvotes: 0