I'm trying to create a string of 116 random characters, I'm terrible at understanding batch files but I managed to create a random number rand from 0 to 15 to get an element from hex_chars=0123456789ABCDEF
But when I try to get and output an element from a string of characters I constantly encounter problems.
@echo off
setlocal enabledelayedexpansion
REM Define the length of the random hex string
set "hex_length=116"
REM Initialize the hex characters
set "hex_chars=0123456789ABCDEF"
REM Variable to store the random hex string
set "random_hex="
REM Loop until the required length is reached
for /L %%i in (1,1,%hex_length%) do (
REM Generate a random number between 0 and 15
set /a "rand=((%random% * %random% + %random% %% 281 * %%i) + %time:~-2%) %% 16"
echo !rand!
REM Returns 0 every time
echo !hex_chars:~%rand%,1!
REM Returns 0123456789ABCDEFrand every time
echo !hex_chars:~!rand!,1!
REM Get the hex character from hex_chars based on the random number
set random_hex=%random_hex%!hex_chars:~%rand%,1!
)
REM Output the random hex string
echo Random Hex (116 chars): !random_hex!
endlocal
pause
I thought to get the hex_string element via for but I didn't figure out how to do it correctly
I tried changing the % and ! and ^ symbols in !hex_chars:~!rand!,1!
Don't worry. The management of variables is one of the most confusing points in Batch files, specially the Delayed Expansion feature. The two key points to remember are these:
You can not use %standard% expansion inside a command when the value of the variable changes in the same command, like inside a FOR loop; you must use !delayed! expansion instead. There are a lot of questions/answers in this site about this point; I suggest you to read this answer or this one.
The second point is that variable expansions can NOT be nested using the same expansion char (%
or !
); you can only place a %normal% expansion inside a !delayed! one. For example: echo !hex_chars:~!rand!,1!
is wrong. You must use a "trick" to avoid such nesting as explained here or here.
If we apply the first point to your code, your %random%
and %time:~-2%
expansions must be !random!
and !time:~-2!
if you want they change in every iteration. And applying the second point, the final working code is this:
@echo off
setlocal enabledelayedexpansion
REM Define the length of the random hex string
set "hex_length=116"
REM Initialize the hex characters
set "hex_chars=0123456789ABCDEF"
REM Variable to store the random hex string
set "random_hex="
REM Loop until the required length is reached
for /L %%i in (1,1,%hex_length%) do (
REM Generate a random number between 0 and 15
set /a "rand=((!random! * !random! + !random! %% 281 * %%i) + !time:~-2!) %% 16"
rem echo !rand!
REM Get the hex character from hex_chars based on the random number
for %%r in (!rand!) do set "random_hex=!random_hex!!hex_chars:~%%r,1!
)
REM Output the random hex string
echo Random Hex (116 chars): %random_hex%
endlocal
pause