Jak używać losowości w skrypcie BATCH?

103

Jak używać losowości w skrypcie BATCH?

IAdapter
źródło
1
dlaczego chcesz to zrobić konkretnie w partii?
Mat
Na
SuperUser

Odpowiedzi:

121

%RANDOM% daje losową liczbę od 0 do 32767.

Używając wyrażenia takiego jak SET /A test=%RANDOM% * 100 / 32768 + 1, możesz zmienić zakres na dowolny (tutaj zakres to [1… 100] zamiast [0… 32767]).

mousio
źródło
9
Biorąc pod uwagę konkretny problem, najprawdopodobniej będziesz używać jakiejś pętli? Wtedy rzeczywiście powinieneś używać opóźnionej ekspansji, np. Via SETLOCAL ENABLEDELAYEDEXPANSIONi using !RANDOM!zamiast %RANDOM%, jak opublikował Eugene.
mousio
14
Bardziej ogólne wyrażenie byłoby %RANDOM% * (%maxval% - %minval% + 1) / 32768 + %minval%; po prostu ustaw minvali maxvalnajpierw na odpowiednie wartości.
mousio
1
Zobacz także odpowiedź
indywa
55

% RANDOM% daje losową liczbę od 0 do 32767.

Możesz kontrolować zakres numerów za pomocą:

set /a num=%random% %%100

- wyświetli liczbę z przedziału od 0 do 99.

Ten:

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

- wyświetli liczbę od 1 do 100.

GaryNg
źródło
8
Zwróć uwagę, że nie będzie to równomiernie dystrybuowane! Biorąc przykład 0 ~ 99, liczby 0 ~ 67 będą występować nieco częściej niż liczby 68 ~ 99, ponieważ 32767 modulo 100 to 67, a nie 0, jak musiałoby być dla równomiernego rozkładu. (To%random% %%100 nie jest magiczna składnia, ale w rzeczywistości%random % %% 100 z jedną spacją mniej, gdzie %%jest po prostu %
znak
Otrzymuję błąd „Brakujący operand”, gdy próbuję to zrobić w systemie Windows 10. Wygląda na to, że potrzebujesz tylko singe% dla modulo.
Calmarius
19

Prawdopodobnie będziesz chciał otrzymać kilka liczb losowych i możesz chcieć określić inny zakres dla każdego z nich, więc powinieneś zdefiniować funkcję. W moim przykładzie generuję liczby od 25 do 30 za pomocą call:rand 25 30. Wynik jest RAND_NUMpo zakończeniu funkcji.

@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
indyw
źródło
thx, pracuj dobrze: jeśli dla / L %% a in (1 1% 3 ') zadzwoń: rand% 1% 2
It Was
5
@echo off & setLocal EnableDelayedExpansion

for /L %%a in (1 1 100) do (
echo !random!
)
Evgeny Gavrin
źródło
4

Możesz to zrobić w ten sposób, który nie wymaga EnableDelayedExpansion

:choosenamea
cls
set /a choosemname=%random%

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

gdzie maxjest Twoje maksimum i minminimum. Nie jest to zbyt wydajne, ponieważ może zająć dużo rund, jeśli twój zasięg jest zbyt mały. Nie będzie to również działać w przypadku liczb większych niż 32767.

calebhk98
źródło
3

Powiedzmy, że chcesz liczbę 1-5; możesz użyć następujących:

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

Lub możesz użyć: ~ 1,1 zamiast: ~ -1,1. Wartość: ~ -1,1 nie jest potrzebna, ale znacznie skraca czas potrzebny do trafienia we właściwy zakres. Powiedzmy, że chcesz liczbę 1-50, musimy wybrać między 2 a 1 cyfrą. Posługiwać się:

    :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

Możesz dodać więcej do tego algorytmu, aby zdecydować między dużymi zakresami, takimi jak 1-1000.

user3542843
źródło
3
Dlaczego miałbyś używać, gotoskoro możesz mieć taką wkładkę jak powyżej? Inne rozwiązania pozwalają jednoznacznie określić zakres. Jaka jest zaleta twojego kodu?
Max Leske
2
set /a number=%random% %% [maximum]-[minimum]

przykład ”

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

da losową liczbę od 100 do 50. Pamiętaj, aby użyć tylko jednego znaku procentu jako argumentu, jeśli nie używasz linii w skrypcie wsadowym!

Jakub
źródło
W systemie Windows 10 podaje liczby od -50 do 49, tak jak powinno. Czy kiedykolwiek naprawdę było inaczej?
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
źródło
1
daj temu trochę spacji, aby
zawierał
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

uproszczone dzięki wielu instrukcjom IF i mnóstwu ((()))

prosty
źródło
1

I po prostu całkowicie przypadkowo dla tych, którzy nie zawsze chcą czarnego ekranu.

@(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

Spowoduje to zmianę koloru ekranu, a oba są losowe.

strance
źródło
1

Jeśli podzielisz przez jakąś dużą wartość, otrzymasz ogromną liczbę duplikatów jeden po drugim. To, co musisz zrobić, to wziąć modulo wartości% 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
źródło
0

oto przykład, który dla ciebie stworzyłem, powinien wyświetlić okno dialogowe z prośbą o wybranie liczby 1-10, w zależności od wybranej liczby, wygeneruje przykład losowej liczby do pliku wsadowego, który nazwałeś. Jeśli wybierzesz "1", otrzymasz przykład losowej liczby jednocyfrowej. jeśli wybierzesz „10”, otrzymasz przykład losowej 10-cyfrowej liczby.

@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
źródło
-1

teraz zawiera wszystkie kolory tęczy 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
randomizowane
źródło
Myślę, że to jest zepsute
A Child of God
-1

I żeby być całkowicie przypadkowym, totalny brak porządku: 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
randomizowane
źródło