<http://www.netikka.net/tsneti/info/tscmd087.htm>
Copyright © 2003-2012 by Prof. Timo Salmi  
Last modified Wed 11-Apr-2012 17:35:06

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



87} How can I create a four-digit random string?

For an instructive example of a CMD-commands-only script creating random strings see "MAKEPASS.CMD Make a randomized password" included in the tscmd.zip package.

There is a inbuilt random generator as given by the XP Command-line reference - Concepts - Command shell overview: The variable %RANDOM% a random in a script will be a decimal number between 0 and 32767.
  @echo off & setlocal enableextensions
  set /a rand_=%random% %% 10000
  set rand_=0000%rand_%
  echo %rand_:~-4%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  rand_=4823
The %% is the remainder (modulo) operator

A catch is present, however. If the output is e.g.
  rand_=0968
a prefix of 0 indicates an octal number if used in calculations. Thus as the above would be an invalid octal number because octal numbers cannot have the digits 8 or 9. To demonstrate
  @echo off & setlocal enableextensions
  set /a x=0968
  endlocal & goto :EOF

The output would be
  C:\_D\TEST>cmdfaq
  Invalid number. Numeric constants are either decimal (17),
  hexadecimal (0x11), or octal (021).
Thus, if it is about numbers to be used in calculations, obviously do not pad leading zeros into the variable.

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host

  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
  ::
  :: Call the command line script which the script host built

  call "%temp%\tmp$$$.cmd"
  ::
  :: Display the result

  echo rand_=%rand_%
  ::
  :: Clean up

  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
  '
  Randomize 'VBS
  MyRandom = Right("0000" & Int(10000*Rnd) , 4) 'VBS
  WScript.StdOut.WriteLine "@set rand_=" & MyRandom 'VBS

The output might be e.g.
  C:\_M>c:\_d\test\cmdfaq
  rand_=7674

To generate a five digit random number between 10000 and 99999
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script

  set skip=
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  :: to generate a five digit random number between 10000 and 99999

  for /f "tokens=*" %%a in ('
    cscript //nologo "%vbs_%" 10000 99999') do (
      set random_=%%a)
  echo random_=%random_%
  ::
  :: Clean up

  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script

  Randomize 'VBS
  Set arg = WScript.Arguments 'VBS
  Wscript.Echo RandomFn(arg(0), arg(1)) 'VBS
  '
  Function RandomFn (low, high) 'VBS
    RandomFn = Int (low + (high - low + 1) * Rnd) 'VBS
  End Function 'VBS

The output might be e.g.
  C:\_M>c:\_d\test\cmdfaq
  random_=72010

One of the options is to use G(nu)AWK. The string is between 0000 and 9999. Leading zeros are added by the solution as needed.
  @echo off & setlocal enableextensions
  ::
  :: Create a random number between 0-9999

  gawk 'BEGIN{srand();printf^
    "@set rand_=%%04d\n",int(10000*rand())}'^
    >"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  ::
  :: Display the result

  echo rand_=%rand_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  rand_=0857

Incidentally, if one only needs two digits one quick-and-dirty alternative is to take the current milliseconds: %time:~9,2%

Consider a slightly different task. Get random numbers from 1 to 52 without any repeats. Like shuffling a deck of cards numbered 1-52. Using VBS-aided scripting and the shuffle algorithm to avoid any repeats we get:
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Set the number of random numbers to be shuffled
  :: Typically 52 would be a deck of cards

  set max_=52
  ::
  :: Build a Visual Basic Script

  set vbs_=%mytemp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6

  set cmd_=%mytemp%\tmp$$$.cmd
  cscript //nologo %vbs_% > %cmd_%
  ::
  :: Call the command line script which the script host built

  call %cmd_%
  ::
  :: Display the results

  for /l %%i in (1,1,%max_%) do echo rand[%%i] = !rand[%%i]!
  ::
  :: Clean up

  for %%f in ("%vbs_%" "%cmd_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script
  '

  Dim maxItems, i, j, k, rand(1000) 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  maxItems=WshShell.ExpandEnvironmentStrings("%max_%") 'VBS
  Randomize 'VBS
  For i = 1 to MaxItems 'VBS
    rand(i) = i 'VBS
  Next 'VBS
  For i = 1 to MaxItems 'VBS
    j = 1 + Int(MaxItems*rnd) 'VBS
    k = rand(i) 'VBS
    rand(i) = rand(j) 'VBS
    rand(j) = k 'VBS
  Next 'VBS
  For i = 1 to MaxItems 'VBS
    WScript.Echo "@set rand[" & i & "]=" & rand(i) 'VBS
  Next 'VBS

The output would be e.g.
  C:\_D\TEST>cmdfaq
  rand[1] = 3
  rand[2] = 6
  :
  rand[50] = 36
  rand[51] = 26
  rand[52] = 40


References/Comments: (If a Google message link fails try the links within the brackets.)
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  Google Groups Mar 20 2005, 1:31 am [M]
  Google Groups Mar 20 2005, 1:49 am [M]
  Google Groups Apr 23 2005, 6:10 pm [M]
  Google Groups Apr 24 2005, 2:38 am [M]
  Google Groups Feb 11 2006, 3:17 pm [M]