0

要求:生成 10k 个由序列号(16 位)后跟随机数字字符串(4 位)组成的唯一数字。选择的武器是 Powershell,因为它是我唯一了解的工具。

遇到的问题:

  1. 使用以下方法生成 10k 个序列号:1400000000000000..1400000000010000 并放入变量中。错误:Int32 的值太大
  2. 通过生成 10k 个 4 位数字Get-Random -Minimum 0001 -Maximum 9999并将它们放入变量中。我只设法获得 1 个随机数。
  3. 使用 Join-Object 组合这两个变量(或者至少这是我希望可以做到的)

如何结合这 3 个命令来获得上面指定的半随机数列表?或者有没有更简单的方法来达到同样的效果?

4

4 回答 4

3
(0..10000).ForEach{ '14000000000{0:00000}{1:0000}' -f $_, (Get-Random 10000) }

结果:

14000000000000004965
14000000000000010114
14000000000000026382
14000000000000038644
14000000000000045435
14000000000000052051
14000000000000061801
14000000000000077046
14000000000000087791
14000000000000098090
14000000000000102712
....

解释:

  • 使用格式运算符 ( -f)来格式化字符串,例如'14000000000{0:00000}{1:0000}'. 有关详细信息,请参阅复合格式
  • 您不必将整个 16 位数字放入 a 中[int32],只需从0..1000前导零开始数到 5 位 ( {0:00000}) 并在其前面加上前缀14000000000
  • 在第二个占位符 ( {1:0000}) 中,放置一个新的随机数,前导零最多 4 位
于 2020-06-25T17:12:14.137 回答
1

iRon 的回答提供了一个优雅的解决方案。

让我通过分别解决第 1 点和第 2 点来补充它:

回复 1。

..范围运算符仅支持[int]( System.Int32) (数字)端点(顺便说一下,这同样适用于 LINQ 的Range方法)。

您可以使用.ForEach()数组方法来解决该问题,如 iRon 的回答中所示。

# Returns a collection of [long] (System.Int64) values.
(0..10000).ForEach({ 1400000000000000 + $_ })

回复 2。

PowerShell [Core] 现在支持允许您在指定范围内请求给定数量的随机数的参数-CountGet-Random

# 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

注意:-Maximum值(与 不同-Minimum包含在内;也就是能返回的最大随机数低 1 , 9998.

Windows PowerShell中,您必须Get-Random循环调用:

# Windows PowerShell
$10kRandomNums = foreach ($i in 1..10000) { Get-Random -Minimum 1 -Maximum 9999 }

在循环中调用 cmdlet 很昂贵;System.Random您可以通过直接使用 .NET 类来显着加快速度:

$rnd = [Random]::new()
$10kRandomNums = foreach ($i in 1..10000) { $rnd.Next(1, 9999) }
于 2020-06-25T20:00:43.603 回答
0

创建唯一序列的经典算法是将所有值放入一个数组中。选择一个值。将数组的最后一个值移动到您刚刚选择该值的位置。然后将数组的大小减一。这会创建数组的副本,因此如果有很多值,请注意调整数组大小导致的额外成本。

一个将值从 0 到 19 的示例是这样的,

$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 ', '

由于该值不适合 int32,请使用 int64。要添加打乱的值,循环是这样工作的,

$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
于 2020-06-25T17:07:43.520 回答
0

与优雅和接受的 iRon 的答案类似,这里是一种生成适用于 SMBIOS 或机箱序列号的 26 位序列号的方法(例如在创建虚拟机时):

"{0:####-####-####-####}-{1:####-####-##}" -f (Get-Random -Minimum 1000000000000000 -Maximum 9999999999999999),(Get-Random -Minimum 1000000000 -Maximum 9999999999)

示例输出结果如下:

5682-4527-3132-4212-5548-2660-46
6433-6848-9306-5822-1601-7101-98
6986-6609-3112-9326-3662-7689-92

参考

于 2021-04-13T15:05:12.710 回答