【问题标题】:Random number generator not random in a batch file随机数生成器在批处理文件中不是随机的
【发布时间】:2019-06-03 22:48:09
【问题描述】:

试图生成一个随机数并将其用于 Windows 批处理脚本文件中的变量值。也许我错过了一些非常基本的东西,但有些东西对我不起作用。

创建了一个名为random_test.bat 的批处理文件,内容如下。

SET rnumber=%random%
echo %random%
pause

连续运行该文件 3 次会产生以下一组输出:

一个

C:\Users\user\Desktop>SET rnumber=28955

C:\Users\user\Desktop>echo 20160
20160

C:\Users\user\Desktop>pause
Press any key to continue . . .

两个

C:\Users\user\Desktop>SET rnumber=29072

C:\Users\user\Desktop>echo 13887
13887

C:\Users\user\Desktop>pause
Press any key to continue . . .

三个

C:\Users\user\Desktop>SET rnumber=29183

C:\Users\user\Desktop>echo 18885
18885

C:\Users\user\Desktop>pause
Press any key to continue . . .

如您所见,命令 echo %random% 会按预期不断生成介于 0 和 32,767 之间的相对随机数。

同时使用%random% 为变量rnumber 设置值不会。它产生一个不那么随机的数字(可能也在 0 到 32,767 之间),但它不是随机的。如果我现在猜测,它似乎在 0 到 32,767 的方向上缓慢增长。

为了澄清脚本在每次执行时都会在第 2 行生成一个随机数(20160、13887、18885...),但第 1 行似乎会生成一个随着批处理文件的每次执行而不断增加的数字(28955、 29072、29183 等在我的多次测试中)。

我已经在两台不同的计算机上试过了,分别是 Windows 7 x64 和 Windows 2012 R2,连续多次运行这个 3 行脚本。

接下来要尝试的是来自完全不同网络的计算机,我想知道这是否与域策略、网络、软件有关..

这是怎么回事?

更新:

当从同一个 CMD 窗口按顺序运行命令时,它按预期工作,但在多次执行同一个批处理文件时却没有。

  • 脚本echo %random% 中的行按预期工作。
  • SET rnumber=%random% 行没有。

(多次执行同一个脚本时)

【问题讨论】:

  • 好吧,你认为什么是“足够随机的”?你多久尝试一次??
  • known behavior - 确实很烦人。
  • @SomethingDark:当您启动一个新的cmd 进程时,随机数生成器使用%time% 进行初始化。您在同一个窗口(=进程)中运行所有测试,因此之间没有重新初始化。双击您的test.bat 几次(在同一秒内),您应该能够复制该问题。 (不要忘记添加pause 以保持窗口打开)
  • 哦,对了,有些人通过双击来运行脚本...
  • @SomethingDark:是的——我也无法适应这个概念......

标签: batch-file random cmd


【解决方案1】:

cmd.exe 中的随机数不适合胆小的人。 %RANDOM% 和 !RANDOM!会带你去那里的。

这个页面,https://ss64.com/nt/syntax-random.html,读起来很有趣。

如果您在受支持的 Windows 平台上,PowerShell 将起作用。

@ECHO OFF
FOR /F %%n IN ('powershell -NoLogo -NoProfile -Command Get-Random') DO (
    SET "RNUM=%%~n"
)
ECHO RNUM is %RNUM%

【讨论】:

  • 请解释你的代码
  • @johnktejik,PowerShell Get-Random 命令的输出是一个随机数。在 PowerShell 控制台中,使用命令 help Get-Random -full 了解更多信息。结果存储在环境变量RNUM中。
【解决方案2】:

提供从评论讨论、外部资源和关于我的原始问题的测试中学到的所有内容的摘要。

批处理脚本中的随机数生成器使用以下算法在打开新的 CMD 窗口时播种初始随机数值。 (从这里 - https://devblogs.microsoft.com/oldnewthing/?p=13673

srand((unsigned)time(NULL));

因此,当两个(或更多)CMD 窗口在同一秒内启动时,%random% 的初始返回值相同。具有相同种子和运行时间(到一秒)的两个 CMD 窗口内的 %random% 的后续返回也相同。

此外,如果 CMD 窗口随后以彼此之间的某些延迟启动,则每个新 CMD 窗口中 %random% 伪变量的第一次返回将远非随机,并且将缓慢增加(0 到 32767 范围)。在我的测试中,每个新窗口的初始种子数每秒增加 3 或 4。

要了解更多信息并找到解决方法,请查看此处:

另请查看@lit 提供的 PowerShell 解决方法。

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多