如何在BATCH脚本中使用随机数?

125

如何在BATCH脚本中使用随机数?


1
你为什么特别想要在批处理中完成这个任务? - Mat
这里有一个非常有趣的SuperUser帖子,与批处理脚本中的随机数相关,值得在这里参考一下... - aschipfl
14个回答

148

%RANDOM% 可以生成一个介于0到32767之间的随机数。

通过使用类似 SET /A test=%RANDOM% * 100 / 32768 + 1 的表达式,您可以将范围更改为任何您想要的值(这里的范围是[1…100]而不是[0…32767])。


9
针对特定问题,你很可能需要使用某种类型的循环。这时,你应该确实使用延迟扩展,例如通过 SETLOCAL ENABLEDELAYEDEXPANSION 命令,并使用 !RANDOM! 代替 %RANDOM%,就像 Eugene 发布的那样。 - mousio
21
更通用的表达式将是 %RANDOM% * (%maxval% - %minval% + 1) / 32768 + %minval%;请先将 minvalmaxval 设置为适当的值。 - mousio
1
请参考indiv的回答 - mousio
为什么 echo random = %random% 总是给我一个在 4000 范围内的数字?(它似乎在缓慢增加) - john k

63

%RANDOM%会随机生成0到32767之间的数字。

您可以使用以下方式控制数字的范围:

set /a num=%random% %%100

- 将生成0到99之间的数字。

这个:

set /a num=%random% %%100 +1

-将生成1~100之间的数字。


15
请注意,这种分布不是均匀的!以0〜99为例,数字0〜67出现的次数会略多于数字68〜99,因为32767模100为67,而不是均匀分布所需的0。 (%random% %% 100不是魔法语法,实际上是%random%%100少一个空格,其中%%只是转义符号“%”,表示取模。) - CherryDT
2
当我在Windows 10上尝试这个操作时,出现了“缺少运算符”的错误。看起来你只需要一个百分号来进行模运算。 - Calmarius
3
如果你在命令行上使用这个内容,那么你需要用到 1%。如果你在 .BAT 文件中使用,则需要 2%。这是因为在 .BAT 文件中,%100 具有特殊含义,即当带有参数执行 .bat 文件时,它是第100个参数。 - Ike Starnes
@IkeStarnes 实际上,批处理只能访问 %9 以内的参数;%100 意味着在 %1 后面加上两个零。 - Neil

21

你可能想要获取多个随机数,并且可能希望能够为每个数字指定不同的范围,所以你应该定义一个函数。在我的示例中,我使用 call:rand 25 30 生成从25到30的数字。然后,在该函数退出后,结果将存储在 RAND_NUM 中。

@echo off & setlocal EnableDelayedExpansion

for /L %%a in (1 1 10) do (
        call:rand 25 30
        echo !RAND_NUM!
)

goto:EOF

REM The script ends at the above goto:EOF.  The following are functions.

REM rand()
REM Input: %1 is min, %2 is max.
REM Output: RAND_NUM is set to a random number from min through max.
:rand
SET /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
goto:EOF

谢谢,工作很好:如果对于/L %%a in (1 1 %3 ') do call:rand %1 %2 - Io-oI

6
@echo off & setLocal EnableDelayedExpansion

for /L %%a in (1 1 100) do (
echo !random!
)

6
set /a number=%random% %% [maximum]-[minimum]

example "

set /a number=%random% %% 100-50

将会给出一个在100和50之间的随机数。如果您不在批处理脚本中使用此行,请确保只使用一个百分号作为操作数!


1
在Windows 10上,它给出了从-50到49的数字,正如它应该做的那样。它以前真的有不同吗? - kilves76

5
您可以采用以下方法完成此操作,无需使用EnableDelayedExpansion
:choosenamea
cls
set /a choosemname=%random%

if %choosemname% GTR %max% goto choosenameb
if %choosemname% LSS %min% goto choosenameb
goto gotnamenow

其中max是您的最大值,min是您的最小值。这种方法不太有效率,如果您的范围太小,可能需要很多轮次。此外,这对于大于32767的数字也不适用。


3
@echo off
title Professional Hacker
color 02
:matrix
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%% 
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%% 
echo %random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%% 
goto matrix

1
请给这段代码添加一些空格,以便它按行显示,例如 @echo off - Sinji58

3

假设你需要一个1-5之间的数字,你可以使用以下代码:

    :LOOP
    set NUM=%random:~-1,1%
    if %NUM% GTR 5 (
    goto LOOP )
    goto NEXT

或者你可以使用:~1,1代替:~-1,1。:~-1,1不是必需的,但它大大减少了命中正确范围所需的时间。假设你想要一个1-50的数字,我们需要在2位数和1位数之间做出决定。使用:

    :LOOP
    set RAN1=%random:~-1,1%
    if %RAN1% GTR 5 (
    goto 1 )
    if %RAN1%==5 (
    goto LOOP )
    goto 2

    :1
    set NUM=%random:~-1,1%
    goto NEXT

    :2
    set NUM=%random:~-1,2%
    goto NEXT

您可以对此算法进行扩展,以便在决定较大范围(例如1-1000)时使用。

3
当你可以使用类似上面的一行代码时,为什么要使用“goto”?其他解决方案让你明确指定范围。你的代码有什么优点?(该问题的原文已被精简为需要翻译的内容) - Max Leske

3

如果你将某个大的值除以一个数,你会得到一连串巨量的重复值。你需要做的是对%RANDOM%的值取模:

@echo off
REM 
SET maxvalue=10
SET minvalue=1

SETLOCAL 
SET /A tmpRandom=((%RANDOM%)%%(%maxvalue%))+(%minvalue%)
echo "Tmp random: %tmpRandom%"
echo "Random:  %RANDOM%"
ENDLOCAL

1
@(IF not "%1" == "max" (start /MAX cmd /Q /C %0 max&X)ELSE set C=1&set D=2&wmic process where name="cmd.exe" CALL setpriority "REALTIME">NUL)&CLS
:Y
title %random%6%random%%random%%random%%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%&color %D%&ECHO %random%%C%%random%%random%%random%%random%6%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%&(IF %C% EQU 46 (TIMEOUT /T 1 /NOBREAK>nul&set C=1&CLS&IF %D% EQU 9 (set D=1)ELSE set /A D=%D%+1)ELSE set /A C=%C%+1)&goto Y

使用多个IF语句和大量的((()))进行简化


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接