1 (изменено: kiber_punk, 2009-07-31 13:04:21)

Тема: CMD/BAT: генерация случайного числа из диапазона значений

Бывают случаи когда необходимо сгенерировать случайное число из определённого диапазона.
Переменная %random% раскрывается в случайное десятичное число от 0 до 32767. На первый взгляд получить от неё что-то полезное не представляется возможным.
Но если задействовать арифметические возможности команды set, то можно получить желаемый результат.
Например, нам необходимо сгенерировать случайное число от 0 до 5:

set /a 1+5*%random%/32768

простой пример "Русской рулетки":

@echo off
set /a RND=2*%random%/32767>NUL
if %RND%==0 (echo Нет)
if %RND%==1 (echo Да)

Для генерации числа из определённого диапазона, следует воспользоваться следующей конструкцией:

SET /A R=MIN+(MAX-MIN+1)*%random%/32768

MIN - минимальное значение
MAX - максимальное значение

Переменная R принимает случайное значение. Переменные MIN и MAX определяют при этом нижнюю и верхнюю границу желаемого числового диапазона (MIN<R<MAX), причем значения могут быть и отрицательными. Выражение (MAX-MIN+1) представляет собой количество элементов в сгенерированном таким образом числовом промежутке.



Пример генератора случайных чисел от -50 до 50:

set MIN=-50
set MAX=50
set /a R=MIN+(MAX-MIN+1) * %random%/32768
echo Random number from range -50..50 : %R%

========================================================================

Вынесем генератор в отдельную функцию:

:RND
set MIN=%1
set MAX=%2
SET /A %3=%MIN%+(%MAX%-%MIN%+1)*%random%/32768

Тогда обращение к функции в скрипте будет выглядеть, примерно, так:

call :RND -10 10 n

-10 - минимальное значение,
  10 - максимальное значение,
  n - возвращаемая переменная содержащая случайное число.

Итак, многообразному применению случайных чисел в командных файлах больше ничто не препятствует. Среди возможных применений - управление итерациями, ветвление для перехода на заданные ветви или файлы, а также параметризация вызовов программ.

2

Re: CMD/BAT: генерация случайного числа из диапазона значений

Случайные числа можно использовать и в качестве указателей на элементы (от 1 до N) заранее определенного списка, как это делается в команде for /f. Следующий пример иллюстрирует генерирование 26-значного шестнадцатеричного кода, который может пригодиться при 128-разрядном шифровании WEP в беспроводных локальных сетях:

@echo off
set I=26
set N=16
set CHAR=0 1 2 3 4 5 6 7 8 9 A B C D E F
:LOOP
set /a R=1+%N%*%random%/32768
for /f "tokens=%R%" %%q in ("%CHAR%") do (set Hex=%%q%Hex%)
Set /a I-=1
If %I% GTR 0 goto LOOP
echo %Hex%

Переменная I определяет длину выдаваемого кода, а значение переменной N должно совпадать с количеством элементов списка CHAR. В принципе представленной программой можно воспользоваться для генерирования случайных паролей. Однако, как видно из параметров цикла for /f, количество элементов списка ограничено числом 31, этого достаточно для стандартного алфавита, но никакой гибкости применения практически не обеспечивает.

=================================================================================================

Больше возможностей предлагает операция над переменными а-ля set VAR=%VAR:~10,5%, при помощи которой из заданной переменной можно извлечь некоторую подстроку в соответствии с величиной смещения («10») и длиной («5»). Указанное смещение возможно задать и случайным образом. Ниже приведен пример, показывающий, как в символьном массиве (CHAR) определяются доступные для генерирования пароля (PW) символы, и выдается случайный пароль длиной в восемь символов:

@echo off
set I=8
set N=65
set CHAR=0123456789$#_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWQYZ
:LOOP
set /a R=%N%*%random%/32768
set PW=!CHAR:~%R%,1!%PW%
set /a I-=1
if %I% GTR 0 goto LOOP
echo %PW%