random strings 2
Over a year ago, I posted about generating random strings. After juggling the problem around with people who knew more ruby than I, we had collectively come up with this:
(1..4).map{(0..?z).map(&:chr).grep(/[a-z\d]/i)[rand(62)]}.join
A visitor named Evan posted a shorter solution, which was based on sorting the string randomly and using a regular expression to pull it out all at once:
((9..?z).map(&:chr).sort_by{rand}*”)[/[a-z\d]{4}/i]
There was only one problem with it. On rare occasion it would return nil because it couldn’t find enough characters in a-zA-Z0-9 next to each other. Hmm. Big problem. A year and two months later I set out to see if I couldn’t use a combination of the two ideas to better shorten the solution. This time I wanted 6 random characters, but that doesn’t really change the code.
by adopting the *” instead of .join trick I save two characters. by re-writing it completely I can save one more and end up with this:
((0..?z).map(&:chr).sort_by{rand}.grep(/\w/)*”)[/[^_]{6}/]
the idea here is that we’re making a randomly sorted string, stripping non word characters, joining, then removing the pesky _ and grabbing 6 characters at the same time. Since we’ve removed non-word characters, we’ll always find at least 6 together in a group. yay! So the record stands at 59 characters for a random string of only a set of [a-zA-Z0-9].
Trackbacks
Use the following link to trackback from your own site:
http://blog.stevensoroka.ca/trackbacks?article_id=60

(0..9).map{0until(c=rand(?z).chr)=~/(?!_)\w/;c}*''
50 chars
(0..9).map{rand(?z).chr[/[^_\W]/]||redo}*”
42 chars (for generating a 10-length random string) :-)