Como usar aleatório no script BATCH?

103

Como usar aleatório no script BATCH?

IAdapter
fonte
1
por que você deseja fazer isso especificamente em lote?
Mat,
Há uma postagem muito interessante sobre SuperUser relacionada a números aleatórios em scripts em lote que vale a pena ser referenciada aqui ...
aschipfl

Respostas:

121

%RANDOM% dá a você um número aleatório entre 0 e 32767.

Usando uma expressão como SET /A test=%RANDOM% * 100 / 32768 + 1, você pode alterar o intervalo para qualquer coisa que desejar (aqui, o intervalo é [1… 100] em vez de [0… 32767]).

mousio
fonte
9
Dado o problema específico, você provavelmente usará algum tipo de loop? Então você realmente deve usar a expansão retardada, por exemplo, via SETLOCAL ENABLEDELAYEDEXPANSIONe usando ao !RANDOM!invés de %RANDOM%, como Eugene postou.
mousio,
14
Uma expressão mais geral seria %RANDOM% * (%maxval% - %minval% + 1) / 32768 + %minval%; apenas defina minvale maxvalcom os valores apropriados primeiro.
mousio
1
Veja também a resposta individual
mousio
55

% RANDOM% fornece um número aleatório entre 0 e 32767.

Você pode controlar o intervalo do número com:

set /a num=%random% %%100

- produzirá um número entre 0 ~ 99.

Este:

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

- produzirá um número entre 1 ~ 100.

GaryNg
fonte
8
Observe que isso não será distribuído uniformemente! Tomando o exemplo 0 ~ 99, os números 0 ~ 67 ocorrerão um pouco mais frequentemente do que os números 68 ~ 99 porque 32767 módulo 100 é 67 e não 0 como teria que ser para uma distribuição uniforme. (Esta %random% %%100não é uma sintaxe mágica, mas na verdade %random % %% 100com um espaço a menos, onde o %%é apenas um escapado %que significa módulo.)
CherryDT
Estou recebendo o erro "Operando ausente" ao tentar fazer isso no Windows 10. Parece que você precisa apenas de um único% para o módulo.
Calmarius
19

Você provavelmente deseja obter vários números aleatórios e pode querer especificar um intervalo diferente para cada um, portanto, deve definir uma função. No meu exemplo, eu gero números de 25 a 30 com call:rand 25 30. E o resultado é RAND_NUMapós a saída dessa função.

@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
indiv
fonte
obrigado, funcione bem: se para / L %% a em (1 1% 3 ') chame: rand% 1% 2
Não fui eu
5
@echo off & setLocal EnableDelayedExpansion

for /L %%a in (1 1 100) do (
echo !random!
)
Evgeny Gavrin
fonte
4

Você poderia fazer desta forma, o que não requer EnableDelayedExpansion

:choosenamea
cls
set /a choosemname=%random%

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

onde maxestá seu máximo e miné seu mínimo. Isso não é muito eficiente, pois pode levar muitas rodadas se seu alcance for muito pequeno. Além disso, isso não funcionará para números maiores que 32.767.

calebhk98
fonte
3

Digamos que você queira um número de 1 a 5; você pode usar o seguinte:

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

Ou você pode usar: ~ 1,1 no lugar de: ~ -1,1. O: ~ -1,1 não é necessário, mas reduz bastante o tempo necessário para atingir o intervalo correto. Digamos que você queira um número de 1 a 50, precisamos decidir entre 2 dígitos e 1 dígito. Usar:

    :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

Você pode adicionar mais a este algoritmo para decidir entre grandes intervalos, como 1-1000.

user3542843
fonte
3
Por que você usaria gotoquando você pode ter um forro como acima? Outras soluções permitem que você especifique explicitamente o intervalo. Qual é a vantagem do seu código?
Max Leske
2
set /a number=%random% %% [maximum]-[minimum]

exemplo "

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

fornecerá um número aleatório entre 100 e 50. Certifique-se de usar apenas um sinal de porcentagem como operando se não estiver usando a linha em um script de lote!

Jacob
fonte
No Windows 10, ele fornece números de -50 a 49, como deveria. Alguma vez realmente aconteceu de outra forma?
kilves76
2
@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
Sinji58
fonte
1
dê alguns espaços para que tenha linhas, como @echo off
Sinji58
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

simplificado com várias instruções IF e bastante ((()))

simples
fonte
1

E apenas para ser completamente aleatório para quem nem sempre quer uma tela preta.

@(IF not "%1" == "max" (start /MAX cmd /Q /C %0 max&X)ELSE set A=0&set C=1&set V=A&wmic process where name="cmd.exe" CALL setpriority "REALTIME">NUL)&CLS
:Y
(IF %A% EQU 10 set A=A)&(IF %A% EQU 11 set A=B)&(IF %A% EQU 12 set A=C)&(IF %A% EQU 13 set A=D)&(IF %A% EQU 14 set A=E)&(IF %A% EQU 15 set A=F)
(IF %V% EQU 10 set V=A)&(IF %V% EQU 11 set V=B)&(IF %V% EQU 12 set V=C)&(IF %V% EQU 13 set V=D)&(IF %V% EQU 14 set V=E)&(IF %V% EQU 15 set V=F)
(IF %A% EQU %V% set A=0)
title %A%%V%%random%6%random%%random%%random%%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%&color %A%%V%&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&SET /A A=%random% %%15 +1&SET /A V=%random% %%15 +1)ELSE set /A C=%C%+1)&goto Y

Isso mudará a cor da tela e ambos são aleatórios.

strance
fonte
1

Se você dividir por algum valor grande, obterá uma grande quantidade de duplicatas, uma após a outra. O que você precisa fazer é pegar o módulo do valor% 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
Kvant
fonte
0

aqui está um exemplo que criei para você, ele deve exibir uma caixa de diálogo pedindo para você selecionar um número de 1 a 10, dependendo do número que você selecionar, ele irá gerar um exemplo de número aleatório para um arquivo em lote que você nomeou. Se você selecionar "1", obterá um exemplo de número aleatório de 1 dígito. se você selecionar "10", obterá um exemplo de número aleatório de 10 dígitos.

@echo off
color f0
set /p "FileName= Enter Filename (Without Extension) : "
echo @echo off >> %FileName%.bat
echo File Created!
pause
cls
:CommandLine
set /p "calc= ~%ComputerName%: Enter a number to recieve the amount of  random digits :"
if %calc%==genrand_help goto GenerateRandomHelp
if %calc%==1 echo echo %%RANDOM:~-1%% >> %FileName%.bat
if %calc%==2 echo echo %%RANDOM:~-1%%%%RANDOM:~-1%% >> %FileName%.bat 
if %calc%==3 echo echo %%RANDOM:~-1%%%%RANDOM:~-1%%%RANDOM:~-1%% >>  %FileName%.bat
if %calc%==4 echo echo %%RANDOM:~-1%%%%RANDOM:~-1%%%%RANDOM:~-1%%%%RANDOM:~-1%% >> %FileName%.bat
if %calc%==5 echo echo %%Random%% >> %FileName%.bat
if %calc%==6 echo echo %%Random%%%%RANDOM:~-1%% >> %FileName%.bat
if %calc%==7 echo echo %%Random%%%%RANDOM:~-1%%%%RANDOM:~-1%% >> %FileName%.bat 
if %calc%==8 echo echo %%Random%%%%RANDOM:~-1%%%%RANDOM:~-1%%%%RANDOM:~-1%% >> %FileName%.bat
if %calc%==9 echo echo  %%Random%%%%RANDOM:~-1%%%%RANDOM:~-1%%%%RANDOM:~-1%%%%RANDOM:~-1%% >>  %FileName%.bat
if %calc%==10 echo echo %%Random%%%%Random%% >> %FileName%.bat  
goto CommandLine
zask
fonte
-1

agora apresentando todas as cores do arco-íris dos

@(IF not "%1" == "max" (start /MAX cmd /Q /C %0 max&X)
  ELSE set C=1&set D=A&wmic process where name="cmd.exe" CALL setpriority "REALTIME">NUL)&CLS
:Y
set V=%D%

(IF %V% EQU 10 set V=A) 
    & (IF %V% EQU 11 set V=B)
    & (IF %V% EQU 12 set V=C)
    & (IF %V% EQU 13 set V=D) 
    & (IF %V% EQU 14 set V=E)
    & (IF %V% EQU 15 set V=F)
title %random%6%random%%random%%random%%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%&color %V%&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 15 (set D=1)ELSE set /A D=%D%+1)
  ELSE set /A C=%C%+1)&goto Y
randomizado
fonte
Acho que está quebrado
Um Filho de Deus
-1

E apenas para ser completamente aleatório, uma total falta de ordem: SET /A V=%random% %%15 +1

@(IF not "%1" == "max" (start /MAX cmd /Q /C %0 max&X)ELSE set C=1&set V=A&wmic process where name="cmd.exe" CALL setpriority "REALTIME">NUL)&CLS
:Y
(IF %V% EQU 10 set V=A)&(IF %V% EQU 11 set V=B)&(IF %V% EQU 12 set V=C)&(IF %V% EQU 13 set V=D)&(IF %V% EQU 14 set V=E)&(IF %V% EQU 15 set V=F)
title %V%%random%6%random%%random%%random%%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%%random%&color %V%&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&SET /A V=%random% %%15 +1)ELSE set /A C=%C%+1)&goto Y
randomizado
fonte