<cfset dummy=randomize(5)> <cfset mynr=randRange(1,10)> <cfoutput>#mynr#</cfoutput>
If your box acts the way mine does, this causes the same number to appear each time: nice for testing but a problem for operation. Now remove the randomize statement and rename the page check2.cfm. It will act the way you want it to: generating a "random" number from 1 to 10.
<cfset mynr=randRange(1,10)> <cfoutput>#mynr#</cfoutput>
Because the password will be written rather than spoken, the emphasis shouldn't be on avoiding similar sounds but on avoiding characters that might be confused in written form. You won't need to generate pronounceable passwords; you want to be sure your passwords that aren't visually confusing.
Therefore, you should avoid certain letters. In certain fonts, capital "I" looks like small "l" (el) which in turn looks like the number 1 (one). Similarly, capital "O" looks like the number 0 (zero). I've seen users get confused by these characters and recommend you avoid them.
There's another reason you can't just generate passwords from the alphabet: profanity. Imagine your user's reaction if your automated system swears at the user.
There's a third reason you can't just work from the alphabet. Security experts tell you to use numbers, special characters, and mixed case letters that don't spell anything.
It is possible, but it's a pain to reject passwords that contain dictionary words embedded in them. However, there's a simpler approach: don't use any vowels. The combination of numbers, mixed case consonants, and special characters produces a good temporary password that will suffice until the user can replace it with something meaningful. In fact, the sheer perversity of the password will probably encourage the user to change it right away. This is good.
Finally, to avoid hard-to-find failures down the road, omit characters that have special meanings or which are hard to distinguish from each other. I omitted the backslash, pipe, single and double quotes, the back quote, pound sign, ampersand, greater-than sign, less-than sign, and the space. (Spaces don't work well for ftp and might get trimmed by accident if on either end of the password). If you find that other characters cause problems (with your database engine perhaps), omit them as well or plan to handle them carefully.
This password is suitable for one-time use. The letters I, L, and O are not used.<br>
Change it to something else after you use it to log on.
<p>
<cfset Odd="!@$%^*()_+[]{}~-=;:,./?">
<cfset Num="1234567890">
<cfset Con="qwrtyupsdfghjkzxcvbnm">
<cfset Pool=Odd&Num&Con&ucase(Con)>
<cfset Poolsize=len(Pool)>
Once you've done this, the outer loop has to perform the test. The findOneOf function is a good one for this situation. If any of the characters in the first string is in the second, it returns true. Thus, the test to be sure each of the four groups is represented by at least one character is a simple one. If the test succeeds, Done is set to true and the outer loop ends. If not, the outer loop resets the password and the inner loop tries again. (If you're coding from scratch, add a counter test to the condition and increment the counter while looping; this keeps you from being very unhappy if your code is somehow flawed.)
<cfset Done=0> <cfloop condition="not Done"> <cfset Newpass=""> <cfset Passlen=randrange(9,12)> <cfloop index="dummy" from="1" to="#Passlen#"> <cfset Char=mid(Pool,randrange(1,Poolsize),1)> <cfset Newpass=Newpass&Char> </cfloop> <cfif findOneOf(Odd,Newpass) and findOneOf(Num,Newpass) and findOneOf(Con,Newpass) and findOneOf(ucase(Con),Newpass)> <cfset Done=1> </cfif> </cfloop> <cfoutput>#Newpass#</cfoutput>