Friends, I am trying to generate a random hex string on my web server. I am using Apache HTTPD on Windows 10. I am using the hex string for session ID's etc.
The code I have tried so far:
setlocal enabledelayedexpansion
set HESSTR=0123456789ABCDEF
set /a tempone="("%RANDOM%"*"16")"
set /a RANHEXS=tempone"/"32767
echo %RANHEXS%
set hexout=!HESSTR:~%RANHEXS%,1!
echo %hexout%
pause
endlocal
But this code Always returns 7... What am I doing wrong?
Thanks a lot!
Here is a method to create a random hexadecimal digit that relies on the undocumented built-in environment variable =ExitCode, which returns the exit code as an 8-digit hexadecimal number:
rem // Set ErrorLevel and exit code to a random number:
cmd /C exit %RANDOM%
rem // Return the last digit of the hexadecimal exit code:
echo %=ExitCode:~-1%
Note that the exit code can reach from 00000000 to FFFFFFFF. The value of RANDOM however covers the range from 0 to 32767, which is 0000 to 7FFF expressed in hexadecimal notation; so you can build a 3-digit hexadecimal number at most by using the last three digits.
#Set /a num=%random% %% 16 + 1
Echo %num% / 16
See set /?. % is defined in the C language as
% The result of the remainder operator is the remainder when the first operand is divided by the second
And we need to escape the % with another %, so %%.
So you divide a number by the range you want - so 165 %% 16 = 5 (the remainder). Then we add 1 to make it 1 to 16 else it would be 0 to 15.
PS CMD is unusual is being 0-32767, most random numbers are between 0 and 1 then you multiply. This is from VBScript's help - Int((upperbound - lowerbound + 1) * Rnd + lowerbound) so (16 - 1 + 1) * RandomNum + 1.
Related
I intended to output the following in a Windows batch file to print five random coordinates wihtin a given range. I know this task is easier on other languages but I'm forced to use Windows batch programming.
INTENDED OUTPUT:
x1:1344
y1:1995
x1:1347
y1:1998
x1:1350
y1:1996
x1:1345
y1:1999
x1:1345
y1:1995
)
My windows batch coding is not that great and I complied the following using Google Fu.
I'm not sure what I'm missing but the following code is supposed to output two random numbers as a coordinate (x1 and y1).
However my code below does not give me my intended output
CODE
#echo off & setlocal EnableDelayedExpansion
for /L %%a in (1 1 5) do (
REM Random X coordinate between 1336 1350)
call:rand 1336 1350
set /A x1= !RAND_NUM!
echo(!x1!)
REM Random Y coordinate between 1950 2000)
call:rand 1950 2000
set /A y1= !RAND_NUM!
echo(!y1!)
)
goto:EOF
:rand
SET /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
goto:EOF
My output is missing the five y coordinates and prints the first five x coordinates first and then one y coordinate and stops.
OUTPUT:
x1:1344
x1:1349
x1:1347
x1:1342
x1:1347
y1:1995)
The closing parenthesis ) inside of the code block is seen as the closing parenthesis of the code block itself, if you really needed them, which you don't you would need to escape them ^) but instead remove them entirely. Also no need to set /A x1 and y1 just set can work on its own, but even that set is not needed:
#echo off & setlocal EnableDelayedExpansion
for /L %%a in (1 1 5) do (
REM Random X coordinate between 1336 1350
call:rand 1336 1350
echo(x1:!RAND_NUM!
REM Random Y coordinate between 1950 2000
call:rand 1950 2000
echo(y1:!RAND_NUM!
)
goto:EOF
:rand
set /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
goto :EOF
I am trying figure out how to keep adding 100 to a variable but keep the zeroes in place. Here is what I mean.
A = 0001
msgbox % (a + 100)
The way it is now gives me "101" instead of "0101". Eventually I want to be able to keep adding 100 to get: 0101, 0201...1001...2101...and so forth.
Displays numeric value padded to length 4 by prefixing 0's
a := 1
msgbox % format( "{1:04}", a + 100 )
Message Box Output
0101
Notes
1 refers to the first argument (a+100)
:04 defines format: width 4 padded by 0's
Format Reference
so i've created a for loop that calculates (x mod 6) + 2 for every number from 1-10 (inclusive), with "x" representing each individual number as the loop increments. however, i'd like to calculate the average for each of the 10 results, but i actually have no idea as to how i'd format the loop to do so. i'd rather not do something like echo "1 + 2 + 3 + etc" as that seems extremely lazy and ill-constructed. i feel like this is something relatively easy, but i've tried searching it up and attempting another loop, but to no avail. any and all help is much appreciated!
here's the loop:
:ForLoop
#echo off &setlocal enabledelayedexpansion
echo This loop calculates the results for (x mod 6) + 2 with x being each number from1-10 (inclusive).
echo.
for /L %%x in (1, 1, 10) do (
SET /a VAR=%%x %% 6+2
set /a CAL=!VAR! %% 8
echo %%x MOD 6 + 2 = !CAL!
)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:ForLoop
echo This loop calculates the results for (x mod 6) + 2 with x being each number from1-10 (inclusive).
echo.
SET /a iterations=10
SET /a sum=0
for /L %%x in (1, 1, %iterations%) do (
SET /a VAR=%%x %% 6+2
SET /a sum+=var
SET /a avg=sum / %%x
echo %%x MOD 6 + 2 = !var! average so far=!avg! (from !sum! / %%x^)
)
GOTO :EOF
There's no need to do the %% 8 jazz - since var can only be (0..5)+2, this gives a range of 2..7.
set /a uses the run-time value of the variables, so !var! is not required - %var% would use the initial value of var.
Note that the average is truncated as batch does integer mathematics.
Could you please advice what using "&" or "^" in SET command means (I haven't found any explanation by using Google).
For example, following Windows batch code block
SET V_COMMAND=3
SET /A V_FLAG="%V_COMMAND%&2"
echo VFlag is: %V_FLAG%
produces:
VFlag is: 2
But I haven't any opinion about what command above does.
Also there is another case with "^":
SET V_COMMAND=3
SET /A V_FLAG="%V_COMMAND%^3"
echo VFlag is: %V_FLAG%
For this case output is:
VFlag is: 0
Since you are using set /a, the indicated characters are bitwise operators:
& = bitwise AND = 1 if both bits are 1
^ = bitwise XOR = 1 if only one of the two bits is 1
So if a is 10 (1010 in binary) and b is 13 (1101 in binary)
1010 1010
1101 1101
---- ----
1000 = a & b 0111 = a ^ b
Or in your case with 3 dec = 11 bin and 2 dec = 10 bin
11 11
10 11
-- --
10 = 3&2 = 2 00 = 3^3 = 0
Those are bitwise operators - & is bitwise AND, and ^ is bitwise XOR. These bitwise operators are only available with SET /A.
How can I calculate bit selection from shell?
Suppose I've got something like: i[m:l]
i is an integer, m is the MSB portion of the bit select and l is the LSB portion of the bit select, e.g.:
250[1:0] - would return the 2 LSB bits of "250", and answer will be "2"
250[7:2] - would return the 6 MSB bits of "250", and answer will be "62"
Not sure how portable this is, but Bash and KSH at least support bitwise operations (left & right shift, bitwise AND and OR), and exponentiation. So you can use those directly to do bitmasks.
#! /bin/sh
extract_bits() {
msb=$1 ; lsb=$2 ; num=$3
# Number of bits required
len=$(( $msb + 1 - $lsb ))
# Bitmask == 2^len - 1
mask=$(( 2 ** $len - 1 ))
# Left-shift mask, bitand, right-shift result
echo $(( ( num & ( $mask << $lsb ) ) >> $lsb ))
}
extract_bits 1 0 250
extract_bits 7 2 250
(As to whether it's a good idea to be doing this at all in a shell script, well, I'm not convinced.)