# Solved: Combining Random Number and Letter Generator



## scrfix (May 3, 2009)

Ok,

I created a random number and modified a random letter generator. These were just for practice however where the problem is coming in is combining these two items.

The random number generator generates a number such as 59483 or 2834
The random letter generator generates a single letter or . - _

I would like to combine these items, I am presuming with a FOR loop and this is where I am failing.

To make things a little easier for the question, let's take an already generated number such as 53942.

I would like to utilize a FOR statement (I am presuming) to go through each one of the characters so 5 times and randomly place random letters anywhere from the beginning, in between each number or at the end.

I have tried about a gazillion FOR loops and I am just not getting it.


```
::@echo off
@echo on
 
:_RandomLetter
set _str=AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz.-_
setLocal EnableDelayedExpansion
set /a _P=!random!%%55
set _str=!str:~%_P%,1!
set /a number=0
If %number% LSS 1234 Call :_RandomNumber
Goto _End
 
:_RandomNumber
 
:_setmax
set /a max=%random%
if %max% LSS 8000 GOTO _setmax
 
:_setmaxrand
set /a maxrand=%random%
if %maxrand% LSS 10000 GOTO _setmaxrand
 
set /a min=%random%%%7999
set /a range=%max%-%min%
set /a minrand=%random%%%9999
set /a rangerand=%maxrand%-%minrand%
set /a rand=%random%%%3
set /a number=(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%))
if %number% LSS 1234 Call :_RandomNumber
GOTO :EOF
:_End
 
:_mixture
For %%J In (%number%) Do (
echo %%J
set /a _P=!random!%%55
set _str=!str:~%_P%,1!
set /a _pw=%%J
set /a _pw=%_pw:~0,1%
echo %_pw%%_str%
)
EndLocal DisableDelayedExpansion
pause
```
This FOR statement I already know isn't working. What am I doing wrong? It only outputs a letter. It doesn't output the number.

What I am hoping to end up with is something similar to the following examples:
1. A5f3b9B4g2i
2. d5n3942s
3. 53942d
4. (Ultimate Goal): 9a3Z5M24b (This one actually mixes up the numbers generated and randomly includes letters in random areas of the number.)

I figured the steps to accomplishing this would be to
1. Have a random number generator. Completed
2. Have a random letter generator. Completed
3. First be able to combine the letters together within a FOR statement. Failed
4. Next, randomize each letter into the numbers (Haven't gotten there yet)
5. Last randomize the number itself (Not there yet)

This is where I am stuck. Any help would be appreciated. This is not necessarily for anything but it is looking promising. It is mainly to help me learn about the FOR loop.

I even tried tokens and it said tokens=1,2,3,4 or * or 1 were not expected at this time.


----------



## TheOutcaste (Aug 8, 2007)

```
:_mixture
For %%J In (%number%) Do (
echo %%J
set /a _P=!random!%%55
[B][COLOR=DarkRed]set _str=!str:~%_P%,1![/COLOR][/B]
set /a _pw=%%J
set /a _pw=[COLOR=DarkRed]%[/COLOR]_pw:~0,1[COLOR=DarkRed]%[/COLOR]
echo [COLOR=DarkRed]%[/COLOR]_pw[COLOR=DarkRed]%[/COLOR][COLOR=DarkRed]%[/COLOR]_str[COLOR=DarkRed]%[/COLOR]
```
*set _str=!str:~%_P%,1!*
this line won't work the way you expect. It will _not_ use the value of _P set in the previous line. It will use the value of _P that was set in line 7.
To work, you would need this:
*set _str=!_str:~!_P!,1!*
But that doesn't work, same reason you can't use all percent signs. And *set _str=%_str:~!_P!,1%* doesn't work either.
But luckily, *Call set _str=%%_string:~!_P!,1%%* will work (I redefined the string to use _string).

It also has a typo; you have *!str* instead of *!_str*. Same typo in line 8

You also have to remember that you redefined *_str* in the RandomLetter section. When you get to the For loop, *_str* is a single character. So unless your random number (_P) is 0, you will not get any output.
You'll need to use a different variable for the extracted letter, so you don't modify the original string. Though I'm guessing that may be what you intended by using *_str* and *str*; *_str* for the single extracted letter, and *str* for the full string. If you change the string definition on line 5 to be str=AaBb etc, then line 8 and 37 should work.

All of the lines that are in the For loop must use ! instead of %
So give this a try (some of the changes in red):

```
::@echo off
@echo on
 
:_RandomLetter
set [COLOR=Red]_string[/COLOR]=AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz.-_
setLocal EnableDelayedExpansion
set /a _P=random%%55
set _str=![COLOR=Red]_string[/COLOR]:~%_P%,1!
set number=0
If %number% LSS 1234 Call :_RandomNumber
Goto _End
 
:_RandomNumber
 
:_setmax
set max=%random%
if %max% LSS 8000 GOTO _setmax
 
:_setmaxrand
set maxrand=%random%
if %maxrand% LSS 10000 GOTO _setmaxrand
 
set /a min=random%%7999
set /a range=max-min
set /a minrand=random%%9999
set /a rangerand=maxrand-minrand
set /a rand=random%%3
set /a number=(((random - minrand) * range) / ((rangerand + min) ^^ rand))
if %number% LSS 1234 Call :_RandomNumber
GOTO :EOF
:_End

:_mixture
For %%J In (%number%) Do (
echo %%J
set /a _P=!random!%%55
[COLOR=Red]Call[/COLOR] set _str=[COLOR=Red]%%_string[/COLOR]:~[COLOR=Red]![/COLOR]_P[COLOR=Red]![/COLOR],1[COLOR=Red]%%[/COLOR]
set /a _pw=%%J
set _pw=[COLOR=Red]![/COLOR]_pw:~0,1[COLOR=Red]![/COLOR]
echo [COLOR=Red]![/COLOR]_pw[COLOR=Red]![/COLOR][COLOR=Red]![/COLOR]_str[COLOR=Red]![/COLOR]
)
EndLocal
pause
```
Though there really is no reason to use a For loop for this. %%J will equal %number%. It will only execute one time. These three lines will do the same as the For loop will.

```
set /a _P=!random!%%55
set _str=!_string:~%_P%,1!
set _pw=%number:~0,1%
```
I wrote the following a while back in another thread. They wanted something to generate a series of random passwords with a specified length. This uses just alphanumeric characters, plus % and ^.
Other punctuation should work as long as it's not a special character.
If you want a quote, it should be the first character in the string. An exclamation point won't work though. I doubt if &, |, >, or < would work either.


```
@Echo Off
Setlocal EnableDelayedExpansion
Set _HowMany=25
Set _RNDLength=8
Set _Alphanumeric="A%%^^BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
Set _Str=%_Alphanumeric%987654321
:_LenLoop
IF NOT "%_Str:~18%"=="" SET _Str=%_Str:~9%& SET /A _Len+=9& GOTO :_LenLoop
SET _tmp=%_Str:~9,1%
SET /A _Len=_Len+_tmp
Set _Test1=0
:_test
Set /A _test1+=1
Set _count=0
SET _rndalphanum=
:_loop
Set /a _count+=1
SET _RND=%Random%
Set /A _RND=_RND%%_Len
SET _rndalphanum=!_rndalphanum!!_Alphanumeric:~%_RND%,1!
If !_count! lss %_RNDLength% goto _loop
Echo Random string is !_rndalphanum!
If %_Test1% lss %_HowMany% Goto _test
```
Jerry


----------



## scrfix (May 3, 2009)

What I was attempting with the FOR loop is if I had generated a 6 digit number with the number generator then it would run the FOR loop for every single number found. I guess that is not how it works. Was just trying to improve my FOR loop skills. Failed miserably.

I did find another really cool script for generating passwords. This one requires input when the script is ran but could be changed really easily I am sure.


```
@echo off
setlocal
set PasswordChars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+#/\[]$*_
if "%~1"=="" (
  echo Please pass the password length as parameter.
  goto leave
)
set PasswordLength=%~1
:Start
echo Generating a %PasswordLength% character password ...
setlocal EnableDelayedExpansion
call :CreatePassword Password
setlocal DisableDelayedExpansion
echo Kennwort: %Password%
goto leave
:: ********************************************************************************
:CreatePassword
set TempVar=%PasswordChars%
set /a PWCharCount=0
:CountLoop
  set TempVar=%TempVar:~1%
  set /a PWCharCount+=1
if not "%TempVar%"=="" goto CountLoop
set TempVar=
set Length=0
:GenerateLoop
set /a i=%Random% %% PWCharCount
set /a Length+=1
set TempVar=%TempVar%!PasswordChars:~%i%,1!
if not "%Length%"=="%PasswordLength%" goto GenerateLoop
set %1=%TempVar%
goto :eof
:: ********************************************************************************
:leave
```
If someone wants it where the length is already set for them, this one will generate a random password with a random password length between 5 to 15 characters long without needing a parameter when you run the script. My IE crashed so I am not sure where I found this script at however it was given in a forum just like this one free and clear.

If you want a longer password length change the following line
set /a PasswordLength=!random!%%15

If you want it to go less than 5 characters change the following line:
If %PasswordLength% LSS 5 GoTo _setPWLength

If you remove
If %PasswordLength% LSS 5 GoTo _setPWLength
The code WILL generate a 0 length password and hang so keep this line in there.
(Jerry, this also answers the question as to whether or not %random% will generate a 0 or 32767(?) number. It will.)


```
@echo off
setlocal
set PasswordChars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+#/\[]$*_
:: if "%~1"=="" (
::   echo Please pass the password length as parameter.
::   goto leave
:: )
:: set PasswordLength=%~1
:_setPWLength
set /a PasswordLength=!random!%%15
If %PasswordLength% LSS 5 GoTo _setPWLength
:Start
echo Generating a %PasswordLength% character password ...
setlocal EnableDelayedExpansion
call :CreatePassword Password
setlocal DisableDelayedExpansion
echo Kennwort: %Password%
goto leave
:: ********************************************************************************
:CreatePassword
set TempVar=%PasswordChars%
set /a PWCharCount=0
:CountLoop
  set TempVar=%TempVar:~1%
  set /a PWCharCount+=1
if not "%TempVar%"=="" goto CountLoop
set TempVar=
set Length=0
:GenerateLoop
set /a i=%Random% %% PWCharCount
set /a Length+=1
set TempVar=%TempVar%!PasswordChars:~%i%,1!
if not "%Length%"=="%PasswordLength%" goto GenerateLoop
set %1=%TempVar%
goto :eof
:: ********************************************************************************
:leave
```


----------



## TheOutcaste (Aug 8, 2007)

Pretty much the same as mine, just different names for the variables.
_Alphanumeric = PasswordChars
_Len = _PWCharCount
_RNDLength = PasswordLength
_RND = i
_rndalphanum = TempVar = Password

The loop to get the length of the PasswordChars string takes 72 iterations, whereas mine only takes 8.

But as they say, there's lots of ways to skin a cat.

Your changes to generate a random length password will work, but it's actually 5 to 14, not 15. And you need to either enable Delayed Expansion before this line, or use % instead of !:
set /a PasswordLength=!random!%%15
Or you get a missing operator error and PasswordLength is set to 1 so it loops infinitely.

And this line is where your 0 comes from; *%random% MOD 15* will give a password length of 0 through 14, so it doesn't indicate if %random% will ever be 0 (1500/15 has a remainder of 0)


----------



## TheOutcaste (Aug 8, 2007)

OK, running a little test

```
@Echo %dbg%Off
:_Loop
Set _tmp=%Random%
If %_tmp%==0 Echo There was a zero>>Ranzero.txt
If %_tmp%==32767 Echo There was a 32767>>Ranzero.txt
Goto _Loop
```
%random will generate 32767. In fact I've gotten three of them in the first minute.
And I've now gotten three zeros as I was typing this, so it is 0-32767 *inclusive*


----------



## scrfix (May 3, 2009)

I made a similar loop like that for my son however mine was just for a joke.

To understand the joke, you have to realize that my son likes his resolution at the largest possible resolution where the icons are so tiny you have to view them with a magnifying glass to see them.

Since Vista doesn't have a full screen option for opening a command prompt, at least not on his Vista Business laptop. I set the command line shortcut to be 640x480 which made it full screen.


```
@echo off
:_witg
Echo Dad is the Greatest!
Goto _witg
```
I then placed it on his desktop just waiting for him to click on it. I was going to place it in his startup but he very rarely ever shuts down the computer.

It was pretty funny, of course mine didn't really serve any purpose other than a joke.


----------



## ghostdog74 (Dec 7, 2005)

See here for a simple vbscript random password generator


----------

