raidz
raidz

Reputation: 31

"ECHO" showing up in the middle of generating random characters for some reason?

So my code here:

@echo off
pause
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set alfanum=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
:a
timeout /t 1
set generator=
FOR /L %%b IN (0, 1, 5) DO (
SET /A rnd_num=!RANDOM! * 62 / 32768 + 1
for /F %%c in ('echo %%alfanum:~!rnd_num!^,1%%') do set generator=!generator!%%c
)

echo %generator%
goto generator

Is slightly broken because sometimes "ECHO" shows up in the middle of generating. for example:

vMECHO8ECHOE <<
DQTGv0
aECx5i
lLECHOO3H <<
cOd4ECHOg <<
6950pC

Help? running on Windows 10 CMD.

Upvotes: 1

Views: 154

Answers (2)

aschipfl
aschipfl

Reputation: 34919

Remove the + 1 from your set /A command line and you will be fine:

set /A "rnd_num=!RANDOM!*62/32768"

Which can be simplified to:

set /A "rnd_num=!RANDOM!%%62"

You actually point past the string in !alfanum!, because the position index for sub-string expansion is zero-based, meaning 0 points to the first character, and 61 to the last one in your 62-character string. Your current code returns 62 as the greatest possible random number, so the sub-string expansion returns an empty string, which lets the echo command in your for /F loop output ECHO is {on|off}., resulting in the result ECHO due to the default token string tokens=1 of for /F.

Anyway, The for /F loop is not necessary, just replace it by the line:

rem /* The standard `for` loop ensures that the value of `!rnd_num!` is expanded
rem    BEFORE delayed sub-string expansion of `!alfanum:~...!` occurs: */
for %%a in (!rnd_num!) do set "generator=!generator!!alfanum:~%%a,1!"

Or (slower):

rem /* The `call` command ensures that the sub-string of `%alfanum:~...%`
rem    is expanded AFTER delayed expansion of `!rnd_num!` occurs: */
call set "generator=!generator!%%alfanum:~!rnd_num!,1%%"

Upvotes: 0

T3RR0R
T3RR0R

Reputation: 2951

Substring modification is 0 indexed. ensure the index you use is EQU to the number of characters - 1

FOR /L %%n IN (0,1,5)Do For /F "delims=" %%c In ( 'SET /A "_r=!RANDOM! %% 62"' )Do (
 Set "generator=!generator!!alfanum:~%%c,1!"
)

Upvotes: 1

Related Questions