How do I get truly random numbers in batch?

2019-09-21 18:00发布

问题:

Everyone uses random numbers at one point or another. So, I need some truly random numbers (not pseudo-random*) generated from the command prompt, I also want a system that generates letters in a code line the size of: set RANDOM=%random% %%2 +1. And am I just trying to catch a non-existent butterfly? *pseudo-random is random that relies on outside info like time, batch's random generator is pseudo-random based on time, to test this open 2 new notepad .bat and name this file 1.bat
1.bat

start 2.bat
@echo off
cls
echo %random%
pause

2.bat

@echo off
cls
echo %random%
pause

What's happening?!? Well this is pseudo-random, as long as there is NO delay between the opening of the batch files, the batch file's numbers will be the same.

回答1:

You're basically asking for entropy pool, and your platform is Windows, right?

Best bet is to use CryptGenRandom() function, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx. You could probably call it from Powershell

UPDATE

Apparently, there is a .NET wrapper for crypto, so you could use it from Powershell

[System.Security.Cryptography.RNGCryptoServiceProvider] $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider

$rndnum = New-Object byte[] 4
# Generate random sequence of bytes 
$rng.GetBytes($rndnum)

# rndnum is filled with random bits
....


回答2:

I don't know how to get a random number in batch file, but in powershell is pretty easy,

You can use the cmdlet Get-Random by itself or specify range like 1..100 | Get-Random

Another option is to call the System.Random .net Object:

$Random = New-Object System.Random
$Random.Next()


回答3:

Well, you may program a Batch file version of one of the tons of existent methods that generate pseudo-random numbers, or look for one that may be programmed in a Batch file with no further complications like The Minimal Standard Random Number Generator, or a simpler version of it like these Two Fast Implementations, and even modify one of they to made it simpler!

@echo off
setlocal EnableDelayedExpansion

rem Pseudo random number generator based on "The Minimal Standard"
rem http://www.firstpr.com.au/dsp/rand31/p87-carta.pdf
rem Antonio Perez Ayala aka Aacini

rem Initialize values
set /A a=16807, s=40

rem APA Modification: use current centiseconds for initial value
for /F "tokens=2 delims=." %%a in ("%time%") do if "%%a" neq "00" set /A s=1%%a %% 100


rem Example of use: generate and show 20 random numbers
for /L %%i in (1,1,20) do (
   call :RandomGen
   echo !rand!
)
goto :EOF



:RandomGen

rem Multiply the two factors
set /A s*=a

rem If the result overflow 31 bits
if %s% lss 0 (
   rem Get result MOD (2^31-1)
   set /A s+=0x80000000
)

rem APA modification: return just the low 15 bits of result (number between 0..32767)
set /A "rand=s & 0x7FFF"

exit /B

Of course, I know this method is not comparable with most of the "standard" methods, but I think it is enough for simple Batch file applications, like games...