Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can I create a four-digit random string?

205 views
Skip to first unread message

Timo Salmi

unread,
Mar 19, 2005, 9:58:44 AM3/19/05
to
DRAFT

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
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(0 & 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

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

All the best, Timo

--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Useful script files and tricks ftp://garbo.uwasa.fi/pc/link/tscmd.zip

William Allen

unread,
Mar 19, 2005, 1:03:29 PM3/19/05
to
"Timo Salmi" wrote in message
> DRAFT
...snip

> MyRandom = Right(0 & Int(10000*Rnd) , 4) 'VBS
> WScript.StdOut.WriteLine "@set rand_=" & MyRandom 'VBS

Two points:
(1) If the generated RND value (which is a random number in the
range 0<=RND<1) happens to be less than .01 then &-ing a
single 0 (which will be treated as a string in the &-ing) will not do,
and the result will have three or fewer digits.

The fix would be:
MyRandom = Right("0000" & Int(10000*Rnd) , 4) 'VBS

(2) The line:


WScript.StdOut.WriteLine "@set rand_=" & MyRandom 'VBS

can be written as:
WScript.echo "@set rand_=" & MyRandom 'VBS
since WScript.echo writes to STDOUT automatically when a
script is run by CSCRIPT.EXE (and not a pop-up window as when
the script is run by WSCRIPT.EXE).

--
William Allen
Free interactive Batch Course http://www.allenware.com/icsw/icswidx.htm
For example Batch Files see: http://www.allenware.com/find?BatchLibrary
Creative Technical Writing - Allen & Company: http://www.allenware.com/


Timo Salmi

unread,
Mar 19, 2005, 1:31:37 PM3/19/05
to
William Allen <_w...@email.com> wrote:
> "Timo Salmi" wrote in message
> > MyRandom = Right(0 & Int(10000*Rnd) , 4) 'VBS

> The fix would be:


> MyRandom = Right("0000" & Int(10000*Rnd) , 4) 'VBS

For a moment I was baffled, because I thought that that was what I
posted. Then I took a closer look and noticed that I had failed to
copy my last version of the test file into the FAQ draft. Thanks. I
could have missed that copying failure.

> (2) The line:
> WScript.StdOut.WriteLine "@set rand_=" & MyRandom 'VBS
> can be written as:
> WScript.echo "@set rand_=" & MyRandom 'VBS
> since WScript.echo writes to STDOUT automatically when a
> script is run by CSCRIPT.EXE (and not a pop-up window as when
> the script is run by WSCRIPT.EXE).

True. I am using the two (StdOut.WriteLine / Echo) interchangeably
in my FAQ since I only use cscript in it.

William Allen

unread,
Mar 19, 2005, 5:31:36 PM3/19/05
to
"Timo Salmi" wrote in message
> William Allen wrote:
> > "Timo Salmi" wrote in message
> > > MyRandom = Right(0 & Int(10000*Rnd) , 4) 'VBS
>
> > The fix would be:
> > MyRandom = Right("0000" & Int(10000*Rnd) , 4) 'VBS
>
> For a moment I was baffled, because I thought that that was what I
> posted. Then I took a closer look and noticed that I had failed to
> copy my last version of the test file into the FAQ draft. Thanks. I
> could have missed that copying failure.

Easily happens during development. I particularly liked the line:


findstr "'%skip%VBS" "%~f0" > %temp%\tmp$$$.vbs

for its way of preventing FINDSTR finding it during 'VBS extraction.

You may want to consider a minor mod to allow a command-line
parameter supplied to the Batch file to specify how many digits
are generated in the random string. Relatively little extra code is
needed to add this flexibility. The version below defaults to your
original 4 digit idea if an invalid parameter (or none) is supplied.
This allows the item still to be introduced under your Draft title:
How can I create a four-digit random string?
but adds flexibility for the user (without requiring it to be used).

Something along these lines (keeping to your coding style):

Lines that don't begin with two spaces have wrapped accidentally
====Begin cut-and-paste (omit this line)


@echo off & setlocal enableextensions
::
:: Build a Visual Basic Script and run it with Microsoft Windows Script Host
findstr "'%skip%VBS" "%~f0" > %temp%\tmp$$$.vbs

cscript //nologo %temp%\tmp$$$.vbs %1 digit>%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

Set arg=WScript.Arguments:Randomize 'VBS
If IsNumeric(arg(0)) Then digit=arg(0) Else digit=4 'VBS
MyRandom = Right(String(digit,"0") & Int(10^digit*RND), digit) 'VBS
Wscript.echo "@set rand_=" & MyRandom 'VBS

====End cut-and-paste (omit this line)

Examples of operation:

============Screen capture
C:\WORK>timodemo
rand_=9436

C:\WORK>timodemo 2
rand_=28

C:\WORK>timodemo 5
rand_=27697

C:\WORK>timodemo 12
rand_=380153834819

C:\WORK>timodemo SomeInvalidParamter
rand_=1119

C:\WORK>
============End screen capture

In the line:
cscript //nologo %temp%\tmp$$$.vbs %1 digit>%temp%\tmp$$$.cmd
the parameter "digit" serves two purposes:
(1) Prevents the 1> conflict arising (conflict with STDOUT redirection)
(2) Supplies an invalid parameter to the VBS script when no parameter
is supplied to the Batch file (so preventing an array out of bounds
error in the VBS), and triggers the default to 4 digits trap.

Dr John Stockton

unread,
Mar 19, 2005, 5:49:10 PM3/19/05
to
JRS: In article <d1hen4$4...@poiju.uwasa.fi>, dated Sat, 19 Mar 2005
16:58:44, seen in news:alt.msdos.batch.nt, Timo Salmi <t...@UWasa.Fi>
posted :

> Randomize 'VBS
> MyRandom = Right(0 & Int(10000*Rnd) , 4) 'VBS

-> MyRandom = Right("000" & Int(10000*Rnd) , 4) 'VBS

Three added zeroes are sufficient.


MyRandom = Right(Int(10000*(1.0 + Rnd)) , 4) 'VBS
MyRandom = Right(10000 + Int(10000*Rnd) , 4) 'VBS

could be faster, since addition should be faster than concatenation.


I have read an assertion in a Microsoft group that VBS may have a less
assured future than Javascript, since the latter possesses standards and
is much more widely used in Web pages. Javascript :

MyRandom = String(10000*(1.0+Math.random())|0).substr(1,4) // ?

How about hex digits, base-26 and base-36 digits ?

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

Timo Salmi

unread,
Mar 20, 2005, 12:08:31 AM3/20/05
to
In article <vT8HY5Cm...@merlyn.demon.co.uk>,
Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
> Timo Salmi <t...@UWasa.Fi> posted :

> > MyRandom = Right(0 & Int(10000*Rnd) , 4) 'VBS

> How about hex digits, base-26 and base-36 digits ?

The solution I have for MS-DOS+Win../95/98/Me uses G(nu)AWK, so it
should work for NT/2000/XP as well

150) Can I convert DEC to HEX in a batch file, and vice versa?

250909 Oct 12 2004 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
tsbat.zip Useful MS-DOS batch files and tricks, T.Salmi

Timo Salmi

unread,
Mar 20, 2005, 12:14:54 AM3/20/05
to
Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
> Timo Salmi <t...@UWasa.Fi> posted :
> MyRandom = Right(Int(10000*(1.0 + Rnd)) , 4) 'VBS
> MyRandom = Right(10000 + Int(10000*Rnd) , 4) 'VBS
> could be faster, since addition should be faster than concatenation.

Yes, but concatenation should be guaranteed to work as desired for
extra long cases. Be that as may, the issue only rises with a huge
number of repeats and then one would probably use something
compiled.

Timo Salmi

unread,
Mar 20, 2005, 12:25:30 AM3/20/05
to
William Allen <_w...@email.com> wrote:
> "Timo Salmi" wrote in message
> You may want to consider a minor mod to allow a command-line
> parameter supplied to the Batch file to specify how many digits
> are generated in the random string. Relatively little extra code is

It is a good idea as such. What I'll do is that I'll refer to your
and John's respective postings in the FAQ. In a way tscmd.zip is not
a complete library but tells the user where build from. In this
particular case the essence is getting the random number into a
fixed number of digits. One can then proceed from that.

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

Message has been deleted

Timo Salmi

unread,
Mar 20, 2005, 1:50:27 AM3/20/05
to
In article <d1j0gf$d...@poiju.uwasa.fi>, Timo Salmi <t...@UWasa.Fi> wrote:
> Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
> > How about hex digits, base-26 and base-36 digits ?
>
> The solution I have for MS-DOS+Win../95/98/Me uses G(nu)AWK, so it
> should work for NT/2000/XP as well
> 150) Can I convert DEC to HEX in a batch file, and vice versa?

DRAFT:

88} How to convert DEC to HEX with a script file, and vice versa?

This can be done e.g. with G(nu)AWK or a Visual Basic Script
(VBScript). The gawk solutions are given below. No error checking
for the correct input format of the digits is included in the
conversion algorithms. To put the results in an environment variable
see the DEC to BIN example in this item.


@echo off & setlocal enableextensions

rem DEC to HEX
::
:: Usage
if [%1]==[] (
echo.
echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
goto :EOF)
::
:: Build an awk source
set awksrc=%temp%\tmp$$$.awk
> %awksrc% echo BEGIN{
>> %awksrc% echo number=%1
>> %awksrc% echo base=16
>> %awksrc% echo digit="0123456789ABCDEF"
>> %awksrc% echo result=""
>> %awksrc% echo while(number!=0)
>> %awksrc% echo {
>> %awksrc% echo i=number-base*int(number/base)
>> %awksrc% echo result=substr(digit,i+1,1)result
>> %awksrc% echo number=int(number/base)
>> %awksrc% echo }
>> %awksrc% echo printf"%%s\n",result
>> %awksrc% echo }
::
:: Run the awk source
gawk -f %awksrc%
::
:: Clean up
for %%f in (%awksrc%) do if exist %%f del %%f
endlocal & goto :EOF

As is seen the above can be easily generalized by changing the
"base" variable. The same goes for the other cases.

In the special case of DEC to HEX gawk inbuilt features can
alternatively be used as a simple shortcut:


@echo off & setlocal enableextensions

rem DEC to HEX
::
if [%1]==[] (
echo.
echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
goto :EOF)
::
gawk 'BEGIN{printf"%%X\n","%1"}'
::
endlocal & goto :EOF

The other way round the HEX to DEC code is


@echo off & setlocal enableextensions

rem HEX to DEC
::
:: Usage
if [%1]==[] (
echo.
echo Usage: %~f0 [HexNumber] to be converted to Decimal
goto :EOF)
::
:: Build an awk source
set awksrc=%temp%\tmp$$$.awk
> %awksrc% echo BEGIN{
>> %awksrc% echo k=1
>> %awksrc% echo d=0
>> %awksrc% echo base=16
>> %awksrc% echo number=toupper("%1")
>> %awksrc% echo i=length(number)+1
>> %awksrc% echo while(i!=1)
>> %awksrc% echo {
>> %awksrc% echo i--
>> %awksrc% echo j=index("123456789ABCDEF",substr(number,i,1))
>> %awksrc% echo d=d+j*k
>> %awksrc% echo k=base*k
>> %awksrc% echo }
>> %awksrc% echo printf"%%s in HEX is %%s in DEC\n",number,d
>> %awksrc% echo }
::
:: Run the awk source
gawk -f %awksrc%
::
:: Clean up
for %%f in (%awksrc%) do if exist %%f del %%f
endlocal & goto :EOF

Finally, let's consider the conversion from decimal to binary. And
putting the result into an environment variable.


@echo off & setlocal enableextensions

rem DEC to BIN
::
:: Usage
if [%1]==[] (
echo.
echo Usage: %~f0 [DecimalNumber] to be converted to Binary
goto :EOF)
::
:: Build an awk source
set awksrc=%temp%\tmp$$$.awk
> %awksrc% echo BEGIN{
>> %awksrc% echo number=%1
>> %awksrc% echo base=2
>> %awksrc% echo digit="0123456789ABCDEF"
>> %awksrc% echo result=""
>> %awksrc% echo while(number!=0)
>> %awksrc% echo {
>> %awksrc% echo i=number-base*int(number/base)
>> %awksrc% echo result=substr(digit,i+1,1)result
>> %awksrc% echo number=int(number/base)
>> %awksrc% echo }
>> %awksrc% echo printf"@set bin_=%%s\n",result
>> %awksrc% echo }
::
:: Run the awk source and the created command script
set myscript=%temp%\tmp$$$.cmd
gawk -f %awksrc%>%myscript%
call %myscript%
::
:: Clean up
for %%f in (%awksrc% %myscript%) do if exist %%f del %%f
::
:: Display the results
echo %1 DEC = %bin_% BIN
endlocal & goto :EOF

William Allen

unread,
Mar 20, 2005, 3:07:22 AM3/20/05
to
"Dr John Stockton" wrote in message
...snip

> MyRandom = Right(Int(10000*(1.0 + Rnd)) , 4) 'VBS
> MyRandom = Right(10000 + Int(10000*Rnd) , 4) 'VBS
>
> could be faster, since addition should be faster than concatenation.

Results from timing a 20,000 line VBS containing the three versions
(two from John Stockton and one from Timo Salmi) and averaging over
five runs (on a relatively old and slow machine):

(a) Timo Salmi's (intended) original
MyRandom = Right("0000" & Int(10000*Rnd) , 4) 'VBS
Time for 20,000 executions 3.43 seconds

(b) John Stockton first version


MyRandom = Right(Int(10000*(1.0 + Rnd)) , 4) 'VBS

Time for 20,000 executions 3.69 seconds

(c) John Stockton second version


MyRandom = Right(10000 + Int(10000*Rnd) , 4) 'VBS

Time for 20,000 executions 3.35 seconds

So there's not much difference between any of those (only around
2% between Timo Salmi and the faster of John Stockton's versions).

However<G>, for those who care so much about such very minor time
differences, personally, I'd code the line far more simply as:

MyRandom = Mid(Rnd,3,4) 'VBS

eliminating all the extra arithmetic entirely ;-)

(d) WA version
MyRandom = Mid(Rnd,3,4) 'VBS
Time for 20,000 executions 2.46 seconds
(or well over 25% faster than the fastest of (a) - (c) above)

For those interested in why this very simple version works at all:
(1) Rnd (the Random function) evaluates to a string such as:
"0.7055475" (always below 1 and greater than or equal to 0).
(2) The Mid function used above extracts from character 3 (the first
one after the decimal point, for 4 more characters.
(3) This produces a string consisting of a 4-digit decimal integer
without any further arithmetic (beyond the Rnd function itself).

Klaus Meinhard

unread,
Mar 20, 2005, 6:27:28 AM3/20/05
to
>> Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
>>> How about hex digits, base-26 and base-36 digits ?

From the 4DOS help files:

@CONVERT[input, output, value]: Converts a numeric string (value) from
one number base (input) to another (output). Valid bases range from 2
to 36.The value must be a positive number between 0 and 2**32-1
(2,147,483,647). No error is returned if value is outside that range.
For example, to convert "1010101" from binary to decimal, use this
syntax:

%@convert[2,10,1010101]


--
* Klaus Meinhard *
www.4dos.info
- 4DOS Info -
- Info for DOS -


Klaus Meinhard

unread,
Mar 20, 2005, 6:23:12 AM3/20/05
to
4DOS users might use the internal @random function, aided by @left to
always display 4 digits:

set str=%@left[4,000%@random[0,9999]]

Al Dunbar

unread,
Mar 20, 2005, 1:11:05 PM3/20/05
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message
news:d1j0se$d...@poiju.uwasa.fi...

> Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
> > Timo Salmi <t...@UWasa.Fi> posted :
> > MyRandom = Right(Int(10000*(1.0 + Rnd)) , 4) 'VBS
> > MyRandom = Right(10000 + Int(10000*Rnd) , 4) 'VBS
> > could be faster, since addition should be faster than concatenation.
>
> Yes, but concatenation should be guaranteed to work as desired for
> extra long cases. Be that as may, the issue only rises with a huge
> number of repeats and then one would probably use something
> compiled.

Going back to the original question: "a four-digit random string", where you
are now generalizing "four" to mean "any given number of", I would strongly
suspect that the (pseudo-) randomness of the resulting string may be
adversely affected by this method.

If Rnd returns a single value you cannot expect to scale it up to more than
about 6 significant digits. If the method given above were extended to
provide 20 "random" digits, you would find many combinations that would
simply never be generated. For any given 7 initial digits, the remaining 13
would be fixed. If Rnd returns a double value, this would extend the number
of "random" digits to about 13.

Also, the Rnd function produces numeric values that are pseudo-random in
nature. The various possible digit patterns in a base ten representation
are, imho, NOT necessarily truly random in nature.

If the purpose is simply to generate a sequence that will be different on
each run, the method should suffice. If there is some need for the set of
digits to be more rigorously random in nature, then a more correct approach
would be to pick each digit randomly from the set of possible digits.

/Al


Al Dunbar

unread,
Mar 20, 2005, 1:24:35 PM3/20/05
to

"William Allen" <_w...@email.com> wrote in message
news:423d2f8d$0$16784$ed26...@ptn-nntp-reader02.plus.net...

Note that the seventh decimal point sometimes appears as an "E", as very
small values are represented in exponential notation. As such, the method
would seem acceptable for digit strings of up to six digits.

/Al

William Allen

unread,
Mar 20, 2005, 1:30:00 PM3/20/05
to
"Al Dunbar" wrote in message
...snip

> Going back to the original question: "a four-digit random string", where you
> are now generalizing "four" to mean "any given number of", I would strongly
> suspect that the (pseudo-) randomness of the resulting string may be
> adversely affected by this method.
>
> If Rnd returns a single value you cannot expect to scale it up to more than
> about 6 significant digits. If the method given above were extended to
> provide 20 "random" digits, you would find many combinations that would
> simply never be generated. For any given 7 initial digits, the remaining 13
> would be fixed. If Rnd returns a double value, this would extend the number
> of "random" digits to about 13.
...snip

The version that I posted, which accepts a parameter specifying the
number of digits (with a default to 4) works up to 15 digits. Any
more and the result of the Int(10^digit*RND) function returns a value
in exponent notation, which makes the Batch file return an unsuitable
exponent style result. Results for 15 digit operation look satisfactory:

============Screen capture
C:\WORK>timodemo.bat 15
rand_=975078761577606

C:\WORK>timodemo.bat 15
rand_=758434474468231

C:\WORK>timodemo.bat 15
rand_=225612819194793

C:\WORK>timodemo.bat 15
rand_=870952785015106

C:\WORK>timodemo.bat 15
rand_=735866725444793

C:\WORK>timodemo.bat 15
rand_=787731349468231

C:\WORK>timodemo.bat 15
rand_=566494166851043

C:\WORK>REM shows exponent style result for digits > 15

C:\WORK>timodemo.bat 16
rand_=376124858856E+15

C:\WORK>
============End screen capture

All such functions are pseudo-random of course, but the use of
Randomize ensures the same list of pseudo-random numbers doesn't
occur each time.

William Allen

unread,
Mar 20, 2005, 1:33:49 PM3/20/05
to
"William Allen" wrote in message

> Results for 15 digit operation look satisfactory:

But do contain some redundancy in the last digits
so probably better to treat usable limit as, say, 12 digits.

--
William Allen


Al Dunbar

unread,
Mar 20, 2005, 1:59:49 PM3/20/05
to

"William Allen" <_w...@email.com> wrote in message
news:423dc15d$0$53972$ed2e...@ptn-nntp-reader04.plus.net...

> "Al Dunbar" wrote in message
> ...snip
> > Going back to the original question: "a four-digit random string", where
you
> > are now generalizing "four" to mean "any given number of", I would
strongly
> > suspect that the (pseudo-) randomness of the resulting string may be
> > adversely affected by this method.
> >
> > If Rnd returns a single value you cannot expect to scale it up to more
than
> > about 6 significant digits. If the method given above were extended to
> > provide 20 "random" digits, you would find many combinations that would
> > simply never be generated. For any given 7 initial digits, the remaining
13
> > would be fixed. If Rnd returns a double value, this would extend the
number
> > of "random" digits to about 13.
> ...snip
>
> The version that I posted, which accepts a parameter specifying the
> number of digits (with a default to 4) works up to 15 digits. Any
> more and the result of the Int(10^digit*RND) function returns a value
> in exponent notation, which makes the Batch file return an unsuitable
> exponent style result. Results for 15 digit operation look satisfactory:

Yes, it *looks* satisfactory, however, I am not convinced that the resulting
digit strings represent a sequence of digits meeting any technical
requirement of randomness or pseudo-randomness.

>
> ============Screen capture
> C:\WORK>timodemo.bat 15
> rand_=975078761577606
>
> C:\WORK>timodemo.bat 15
> rand_=758434474468231
>
> C:\WORK>timodemo.bat 15
> rand_=225612819194793
>
> C:\WORK>timodemo.bat 15
> rand_=870952785015106
>
> C:\WORK>timodemo.bat 15
> rand_=735866725444793
>
> C:\WORK>timodemo.bat 15
> rand_=787731349468231
>
> C:\WORK>timodemo.bat 15
> rand_=566494166851043
>
> C:\WORK>REM shows exponent style result for digits > 15
>
> C:\WORK>timodemo.bat 16
> rand_=376124858856E+15
>
> C:\WORK>
> ============End screen capture
>
> All such functions are pseudo-random of course, but the use of
> Randomize ensures the same list of pseudo-random numbers doesn't
> occur each time.

Understood, however, even this does not mean that the results are truly
random or pseudo-random, merely that the non-randomness (if any) of the
patterns is not obvious. I agree that, in many cases, this will suffice. But
it may not meet rigorous standards or randomness if that is what is truly
needed.

/Al


Al Dunbar

unread,
Mar 20, 2005, 2:01:03 PM3/20/05
to

"William Allen" <_w...@email.com> wrote in message
news:423dc242$0$24982$ed2e...@ptn-nntp-reader04.plus.net...

Same conclusion I came to assuming that Rnd returns a "double".

/Al


Timo Salmi

unread,
Mar 20, 2005, 3:02:13 PM3/20/05
to
In article <d1j6fj$h...@poiju.uwasa.fi>, Timo Salmi <t...@UWasa.Fi> wrote:
> DRAFT:
> 88} How to convert DEC to HEX with a script file, and vice versa?
> This can be done e.g. with G(nu)AWK or a Visual Basic Script

> Finally, let's consider the conversion from decimal to binary. And
(the gawk solution omitted)

A VBScript-aided solution for the Decimal to Binary conversion is
given below


@echo off & setlocal enableextensions
rem DEC to BIN
::
:: Usage
if [%1]==[] (
echo.
echo Usage: %~f0 [DecimalNumber] to be converted to Binary
goto :EOF)
::

:: Build a Visual Basic Script and run it with Microsoft Windows Script Host
findstr "'%skip%VBS" "%~f0" > %temp%\tmp$$$.vbs

cscript //nologo %temp%\tmp$$$.vbs %1 > %temp%\tmp$$$.cmd
::
:: Utilize the output and display the result
call %temp%\tmp$$$.cmd
echo Decimal %1 in Binary = %bin_%
::
:: Clean up
for %%f in (%temp%\tmp$$$.vbs %temp%\tmp$$$.cmd) do if exist %%f del %%f
endlocal & goto :EOF
'
number=WScript.Arguments.Unnamed(0) 'VBS
base=2 'VBS
digit="0123456789ABCDEF" 'VBS
result="" 'VBS
While number <> 0 'VBS
i = number - base * Int(number/base) 'VBS
result = Mid(digit,i+1,1) & result 'VBS
number = Int(number/base) 'VBS
Wend 'VBS
WScript.Echo "@set bin_=" & result 'VBS
An example of the output
C:\_D\TEST>cmdfaq 12
Decimal 12 in Binary = 1100

Since VBScript has a Hex function, for the Decimal to Hexadecimal
the while loop and the three lines above it can simply be replaced
with
result = Hex(number) 'VBS
The same goes for octal.

William Allen

unread,
Mar 20, 2005, 3:53:09 PM3/20/05
to
"Al Dunbar" wrote in message
> "William Allen" wrote in message
...snip

> > (d) WA version
> > MyRandom = Mid(Rnd,3,4) 'VBS
> > Time for 20,000 executions 2.46 seconds
> > (or well over 25% faster than the fastest of (a) - (c) above)

> Note that the seventh decimal point sometimes appears as an "E", as very


> small values are represented in exponential notation. As such, the method
> would seem acceptable for digit strings of up to six digits.

Noted. Although the (E)xponent format won't affect the appearance
of the output for very small values returned by Rnd and strings of
up to six digits, it will skew the randomness of the output (because
the digits extracted will have been shifted so that the first digit
following the decimal point will be non-zero) . So more reliable
would be this slightly slower version 2:

(e) WA version 2
MyRandom = Mid(1+Rnd,3,4) 'VBS
Time for 20,000 executions 2.69 seconds
(or 20% faster than the fastest of (a) - (c) in previous post)

Adding 1 prevents the default to (E)xponent format for very
small values returned from Rnd.

Dr John Stockton

unread,
Mar 20, 2005, 3:23:14 PM3/20/05
to
JRS: In article <d1j6fj$h...@poiju.uwasa.fi>, dated Sun, 20 Mar 2005
08:50:27, seen in news:alt.msdos.batch.nt, Timo Salmi <t...@UWasa.Fi>
posted :
>

>88} How to convert DEC to HEX with a script file, and vice versa?
>
>This can be done e.g. with G(nu)AWK or a Visual Basic Script
>(VBScript).
> ...

I don't recall what facilities VBScript offers for this, but it's nearly
a one-liner in javascript, apart from getting and returning the value,
for values exactly represented by IEEE Doubles and radices 2..36 :
Q = parseInt(InString, /radix/)
OutString = Q.toString(/radix/)
It might be a good example of javascript/WSH.

IIRC, my batfiles.htm has something, but not enough, on handling the
Environment.

Dr John Stockton

unread,
Mar 20, 2005, 4:35:31 PM3/20/05
to
JRS: In article <423d2f8d$0$16784$ed26...@ptn-nntp-reader02.plus.net>,
dated Sun, 20 Mar 2005 08:07:22, seen in news:alt.msdos.batch.nt,
William Allen <_w...@email.com> posted :

>However<G>, for those who care so much about such very minor time
>differences, personally, I'd code the line far more simply as:
>
> MyRandom = Mid(Rnd,3,4) 'VBS
>
>eliminating all the extra arithmetic entirely ;-)
>
>(d) WA version
> MyRandom = Mid(Rnd,3,4) 'VBS
> Time for 20,000 executions 2.46 seconds
> (or well over 25% faster than the fastest of (a) - (c) above)
>
>For those interested in why this very simple version works at all:
>(1) Rnd (the Random function) evaluates to a string such as:
> "0.7055475" (always below 1 and greater than or equal to 0).
>(2) The Mid function used above extracts from character 3 (the first
> one after the decimal point, for 4 more characters.
>(3) This produces a string consisting of a 4-digit decimal integer
> without any further arithmetic (beyond the Rnd function itself).


(1) - for a broad enough definition of "such as".

(2) is untrue, or at least not *always* true.
There is a slight chance that Rnd may give 0 or 0.5 or 0.25 0.75 or
0.125 0.375 0.625 0.875 - in that case the Mid function will grope in
vain for the final 4, 3, 2, or 1 digits of the desired tetrad. The
chance will be, in pseudo-Pascal terms, 8 in Max(RandSeed)+1 per go; the
consequences of not getting the correct number of digits cannot be
estimated.

But the powerful theorem of Murphy says that it will happen when least
expected and most embarrassing.

One could append "00000" to Rnd to be sure of getting enough digits.


(3) therefore is not absolutely true; getting four digits is not
guaranteed.


In my version of VBScript, a similar language, there is a much greater
problem; numbers under 0.1 are rendered in E-format, which adversely
affects the chances of the first selected character being a zero.
Obviously anyone using your method should be sure that his system does
not do the same.


Donald E Knuth :-
"Random numbers should not be generated with a method chosen at random".

--
© John Stockton, Surrey, UK. *@merlyn.demon.co.uk / ??.Stoc...@physics.org ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Correct <= 4-line sig. separator as above, a line precisely "-- " (SoRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SoRFC1036)

Todd Vargo

unread,
Mar 21, 2005, 12:57:21 AM3/21/05
to

"Dr John Stockton" <sp...@merlyn.demon.co.uk> wrote in message
news:AWNcJJEj...@merlyn.demon.co.uk...

> JRS: In article <423d2f8d$0$16784$ed26...@ptn-nntp-reader02.plus.net>,
> dated Sun, 20 Mar 2005 08:07:22, seen in news:alt.msdos.batch.nt,
> William Allen <_w...@email.com> posted :
>
> >However<G>, for those who care so much about such very minor time
> >differences, personally, I'd code the line far more simply as:
> >
> > MyRandom = Mid(Rnd,3,4) 'VBS
> >
> >eliminating all the extra arithmetic entirely ;-)
...

> There is a slight chance that Rnd may give 0 or 0.5 or 0.25 0.75 or
> 0.125 0.375 0.625 0.875 - in that case the Mid function will grope in
> vain for the final 4, 3, 2, or 1 digits of the desired tetrad.

...

> In my version of VBScript, a similar language, there is a much greater
> problem; numbers under 0.1 are rendered in E-format, which adversely
> affects the chances of the first selected character being a zero.
> Obviously anyone using your method should be sure that his system does
> not do the same.

Try 'Left(Rnd*1000000,4)' in your timing comparisons.
ISTM sufficient to return reliable 4 digit numbers.

--
Todd Vargo (double "L" to reply by email)

William Allen

unread,
Mar 21, 2005, 4:18:50 AM3/21/05
to
"Todd Vargo" wrote in message
...snip

> Try 'Left(Rnd*1000000,4)' in your timing comparisons.
> ISTM sufficient to return reliable 4 digit numbers.

Timed under the same conditions and same machine
as previous timings:

(f) ToddV version
MyRandom=Left(Rnd*1000000,4) 'VBS
Time for 20,000 executions 2.71 seconds
(or 19% faster than the fastest of (a) - (c) in previous post)

Good solution, and fast, too. All these timings are a fairly
minor issue, but by _actually_ doing the timing, Todd's code
shows that it's faster to extract the digits with a string function,
Left(), than to use an arithmetic function such as INT.

Although people sometimes think arithmetic is faster than
string handling, for smallish strings (a few dozen bytes), it
isn't. If you look at High Level Language code in the
"view underlying assembly code" option that is in many
compilers, you see that 90% or more of the code for say,
* (multiply) or + (add) is code checking whether or not there
are overflows, or that variables are numeric and so on. The
actual assembly language MUL / FMUL or ADD / FADD can
hardly be seen buried amidst all the checking and validating
(this is because people expect HLL code to fall over gracefully
rather than BlueScreen every time your numbers are too big).
Much less such overhead is needed in a piece of string handling.

Note:
MUL = integer multiplication instruction
FMUL = floating point processor multiplication instruction

--
William Allen


Dr John Stockton

unread,
Mar 21, 2005, 8:01:21 AM3/21/05
to
JRS: In article <Z0j%d.740731$6l.350915@pd7tw2no>, dated Sun, 20 Mar
2005 18:11:05, seen in news:alt.msdos.batch.nt, Al Dunbar <alan-no-drub-
sp...@hotmail.com> posted :

>
>Going back to the original question: "a four-digit random string", where you
>are now generalizing "four" to mean "any given number of", I would strongly
>suspect that the (pseudo-) randomness of the resulting string may be
>adversely affected by this method.
>
>If Rnd returns a single value you cannot expect to scale it up to more than
>about 6 significant digits. If the method given above were extended to
>provide 20 "random" digits, you would find many combinations that would
>simply never be generated. For any given 7 initial digits, the remaining 13
>would be fixed. If Rnd returns a double value, this would extend the number
>of "random" digits to about 13.


(1) I believe, without looking for proof, that floats, including Rnd,
will be IEEE Doubles.

But one must not presume that such a function can produce any of the
O(2^53) IEEE Doubles in the range, although it may do so. In Pascal and
at least several versions of Delphi, the result of Random is obtained
from RandSeed, which is a 32-bit quantity (updated each time by RD :=
(RS*a+b) mod 3^32); therefore, only 2^32 values are possible. My copy
of Javascript, I believe, does better.


>Also, the Rnd function produces numeric values that are pseudo-random in
>nature. The various possible digit patterns in a base ten representation
>are, imho, NOT necessarily truly random in nature.

Provided that the representation does not slip into E-form when the
leading digit (or digits) is 0, and providing that the least digit taken
is "worth" considerably more than the least bit of the binary is, I
expect no problem (no such method is appropriate for crypto work, of
course).

>If the purpose is simply to generate a sequence that will be different on
>each run, the method should suffice. If there is some need for the set of
>digits to be more rigorously random in nature, then a more correct approach
>would be to pick each digit randomly from the set of possible digits.

Yes; and it's almost certainly easier to understand the set of possible
defects.

There is one further possible problem; if Randomise uses time-of-day to
initialise the seed, and if the script is scheduled to run at the same
time each day, the available diversity of starting-points will be much
diminished. I recall a University computing section, some while ago,
being considerably interested on having that pointed out when they were
about to start a week of business games starting at 09:00 daily.

Related discussion in <URL:http://www.merlyn.demon.co.uk/pas-rand.htm>
and <URL:http://www.merlyn.demon.co.uk/js-randm.htm>.

JRS: In article <Ddj%d.740927$6l.451854@pd7tw2no>, dated Sun, 20 Mar
2005 18:24:35, seen in news:alt.msdos.batch.nt, Al Dunbar <alan-no-drub-
sp...@hotmail.com> posted :


>
>Note that the seventh decimal point sometimes appears as an "E", as very
>small values are represented in exponential notation. As such, the method
>would seem acceptable for digit strings of up to six digits.

That will slightly affect the probabilities of the digits; there's a
bound on the number of consecutive zeroes after the decimal point before
E-notation appears; so the probability of zeroes is diminished. That
effect is serious in (my) VBScript, where anything under 0.1 is E-form,
so the probability of the first "random" digit being zero is a tenth of
what it should be.

Is your true E-mail address supposed to be obvious?

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; Win98. ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

Dr John Stockton

unread,
Mar 21, 2005, 6:17:23 PM3/21/05
to
JRS: In article <3a76auF...@individual.net>, dated Mon, 21 Mar
2005 00:57:21, seen in news:alt.msdos.batch.nt, Todd Vargo
<todd...@alvantage.com> posted :

>
>Try 'Left(Rnd*1000000,4)' in your timing comparisons.
>ISTM sufficient to return reliable 4 digit numbers.

Rnd returns a value 0 <= x < 1.0. If the value returned is less that
0.001, then on multiplying by a million one gets less than 1000, i.e.
fewer than four digits before the decimal point. That will happen 0.1%
of the time. Without Randomize, I get it on the 125th attempt; with
Randomize, I get it about half of the time per run of 1000 points.

Also, the leading digit will only be zero if the next character is a
decimal point.

--

William Allen

unread,
Mar 21, 2005, 7:20:46 PM3/21/05
to
"Dr John Stockton" wrote in message
> Todd Vargo posted :

> >
> >Try 'Left(Rnd*1000000,4)' in your timing comparisons.
> >ISTM sufficient to return reliable 4 digit numbers.
>
> Rnd returns a value 0 <= x < 1.0. If the value returned is less that
> 0.001, then on multiplying by a million one gets less than 1000, i.e.
> fewer than four digits before the decimal point. That will happen 0.1%
> of the time. Without Randomize, I get it on the 125th attempt; with
> Randomize, I get it about half of the time per run of 1000 points.
>
> Also, the leading digit will only be zero if the next character is a
> decimal point.

Noted.

(g) WA version 3
MyRandom=Right(FormatNumber(Rnd,4),4) 'VBS
Time for 20,000 executions 3.23 seconds
(or 3.5% faster than the fastest of (a) - (c) in previous post)

--
William Allen


Todd Vargo

unread,
Mar 21, 2005, 9:43:13 PM3/21/05
to

"William Allen" <_w...@email.com> wrote in message
news:423f6545$0$81025$ed2e...@ptn-nntp-reader04.plus.net...

Doh! I completely ignored the most elementary rule of mathematics. Zero
times anything remains zero.

Hmm, what about... 'Mid(Rnd+.0001,3,4)' any side effects here? ;-)

William Allen

unread,
Mar 22, 2005, 1:41:39 AM3/22/05
to
"Todd Vargo" wrote in message
...snip
> Hmm, what about... 'Mid(Rnd+.0001,3,4)' any side effects here? ;-)

It's fast and neat, and _nearly_ all the results will be OK, but in
some rare cases an addition can produce whole number effects.
Suppose, for example, Rnd happens to return 0.9999000000 then:

0.9999000000 + .0001 = 1 and the result of Rnd+.0001 will be
presented as a single byte string "1" unless you do some
further arithmetic on it or apply FormatNumber.

The trouble is, even if only one case fails, you need a check
to ensure you haven't hit that one case. And adding another
statement to check (in a High Level Language) would slow
it down and complicate it.

--
William Allen


Todd Vargo

unread,
Mar 22, 2005, 5:40:53 PM3/22/05
to

"William Allen" <_w...@email.com> wrote in message
news:423fbe6a$0$29275$ed26...@ptn-nntp-reader03.plus.net...

I'm getting real sloppy. :(

William Allen

unread,
Mar 22, 2005, 6:19:57 PM3/22/05
to
"Todd Vargo" wrote in message
...snip
> I'm getting real sloppy. :(

No, just full of ideas :-) In the NG, it's much better to throw
out new ideas for others to criticise or improve than to keep
quiet in case you make a mistake. That way you make use
of the nit-pickers, and it keeps them happy, too<G>.

--
William Allen


0 new messages