To read the article online, visit http://www.4GuysFromRolla.com/webtech/010500-3.shtml

# A Follow-Up to Generating Random Passwords

By Ragnvald Larsen

This is part of Marks mail:

 The passwords do not always come back as "n" length. Sometimes they are 1, or even 2 characters short. Is this on purpose? I wanted to ask before I tried to determine exactly why - FYI - I simply set up a `FOR ... NEXT` loop with ten iterations, to start and found the short passwords on the first run through. I was kind of surprised!

After someworking we found the error. Quoting Mark again in a more recent mail:

 Ah ha! I got it. Sometimes the line: ``` c = Mid(strConsonants, Len(strDoubleConsonants) * Rnd + 1, 1) ``` gives you a starting position that is greater then the length of the string. I am going to figure `R=Len(strDoubleConsonants)*Rnd+1` and then compare that value to the actual length. It will have to be done to each of them, but for a length of ten, it came back with `10.75024223327649` which yields a null on the `MID` command.

So the solution was quite simle. My reply to Mark:

 As you said the random values sometimes causes it to choose a character that is not in the list. Obviously the `Mid` character alows non-integers as arguments, but rounds upwards! `Int` returns the integer portion of a number. In this case from 1 to n. The fix thus involves adding `Int()` in the Start-part of the argument in the `Mid()`-function: ``` c = Mid(strDoubleConsonants, Int(Len(strDoubleConsonants) * Rnd + 1), 1) ```

Thus the relevant part to fix is as follows (cut and paste):

 ``` For i = 0 To nLength 'Get a random number number between 0 and 1 nRnd = Rnd 'Simple or double consonant, or a new vocal? 'Does not start with a double consonant '15% or less chance for the next letter being 'a double consonant If GeneratePassword <> "" AND _ (bMadeConsonant <> True) AND _ (nRnd < 0.15) Then 'double consonant c = Mid(strDoubleConsonants,_ Int(Len(strDoubleConsonants) * Rnd + 1), 1) c = c & c i = i + 1 bMadeConsonant = True Else '80% or less chance for 'the next letter being a consonant, 'depending on wether the 'last letter was a consonant or not. If (bMadeConsonant <> True) And (nRnd < 0.95) Then 'Simple consonant c = Mid(strConsonants, _ Int(Len(strConsonants) * Rnd + 1), 1) bMadeConsonant = True '5% or more chance for the 'next letter being a vocal. 100% if last 'letter was a consonant - theoreticaly speaking... Else 'If last one was a consonant, make vocal c = Mid(strVocal, _ Int(Len(strVocal) * Rnd + 1), 1) bMadeConsonant = False End If End If 'Add letter GeneratePassword = GeneratePassword & c Next ```

• Test the new script!

 I saw the source code for your randomly generated passwords. I happen to have a nifty little use for such a routine, so I decided to check the uniqueness of the passwords. You know, if I used 6 characters, how many times could I call your routine before I got the exact same password back.

If the password starts with a consonant and is supposed to be 4 characters long it will generate between 6400 and 12800 different passwords. Starting with a vocal and having a lengt of 4 characters the numbers of passwords will statistically be between 4000 and 6400 different passwords. There is a 15% chance that the password will start with a consonant.

Six character passwords would amount to at least 46656 (6**6) possible passwords. However this is not very likely as the possibility of getting only vocals is 0.15^6 - indeed a small number...

Theoretically speaking...

BUT the `rnd`-function heavily relies on seeding. Using a loop you might experience a lot of similar passwords... While running a loop generating 1000 passwords I experienced as little as 37 different passwords. Adding a pause with additional randomizing in the loop made the number of different passwords go up to about 800. Using more variances will make it even better. Seeding with timeslices only on a fast server is thus NOT a good idea!

One should also use some extra individual variable like the length of the persons name or email adress if you want to generate a lot of passwords...

For making more passwords it is possible to add CAPITALS to the string constants like here:

 ``` Const strDoubleConsonants = "bBdDfFgGlLmMnNpPsStT" Const strConsonants = "bBcCdDfFgGhHkKlLmMnNpPqQrRsStTvV" Const strVocal = "aAeEiIoOuU" ```

Which gives at least 2985984 (12^6) possible passwords as a minimum with a password length of 6 characters.

The algoritm surely (0,15^12) adds consonants from a pool of 16 consonants and thus makes it more readable and even more variable.

If someone would find it interesting to do some in-depth statistical pondering they are most welcome! :-)

Happy Programming!

Attachments: