Re: Random Text: There's got to be an easier way
by Beatnik (Parson) on Jun 03, 2001 at 21:14 UTC
|
my @chars = ("a".."z","A".."Z");
my $random_string = join("",@chars[map{ rand @chars} (1..8)]));
#8 being the number of chars to randomize ofcourse
Greetz
Beatnik
... Quidquid perl dictum sit, altum viditur. | [reply] [d/l] |
|
Beatnik nailed it, but he left out the numerals 2 through 9 and added an extra parenthesis to the second line. The exact solution is thus:
use strict;
my @chars = ("a".."z","A".."Z", 2..9);
my $random_string = join("",@chars[map{ rand @chars} (1..8)]);
#8 being the number of chars to randomize ofcourse
print "$random_string\n";
| [reply] [d/l] |
|
The code described in the Cookbook also includes some non-alphanumeric chars...
I'm pretty confident the code mentioned above is faster than other stuff (but then again, I didn't write it so that's normal).
BTW you left out 1 :)
Greetz
Beatnik
... Quidquid perl dictum sit, altum viditur.
| [reply] |
|
Thanks!
Funny. It must have just been the quotes that I was missing.
Another reason to read the Cookbook, which I just recently purchased (along with Programming Apache Modules with Perl and C)
Have I got some reading (and re-reading) to do. . .
| [reply] |
Re: Random Text: There's got to be an easier way
by VSarkiss (Monsignor) on Jun 03, 2001 at 21:28 UTC
|
Well, your @seed array is only 34 elements long -- which is not a big deal. Basically, you're looking for something that maps the range of numbers returned from the rand function to your desired set. If you had a less complicated filter (say, "any printable character"), then you could use an algorithmic approach, but for this small size, a lookup array is probably the best fit.
As for using strict, you just have to quote the letters in the range. Here's your same code a little shorter:
my @seed = ('a'..'z', 2..9);
my $rand = '';
$rand .= $seed[rand(@seed)] foreach 1..7;
HTH | [reply] [d/l] [select] |
|
Again, the beautiful thing about perl is that there can be many different ways to do the same thing simply and elegantly. Thanks to all for the quick help!!
This is pretty much the code what I was looking at, though I need to learn to use "join" as beatnik pointed out above.
The final version for me, unless someone gives me a compelling reason to use "join".
my @seed=('a'..'z',2..9);
my $rand='';
foreach(0..7){
$rand.=$seed[rand(@seed)];
}
| [reply] [d/l] |
|
Benchmark, nuff said
Greetz
Beatnik
... Quidquid perl dictum sit, altum viditur.
| [reply] |
(dws)Re: Random Text: There's got to be an easier way
by dws (Chancellor) on Jun 04, 2001 at 00:26 UTC
|
... the ids are meant to be relatively human readable ...
If the ids might be spoken (say, to an agent over the phone), you might consider producing them according to an easy-to-speak, easy-to-hear pattern. Something like
Consonant-vowel-consonant-digit
Consonant-vowel-consonant-digit
By using a predictable pattern, miscommunication is minimized. Since an agent knows to listen for a digit in the fourth and eighth position, zero and one are unambiguous.
If you're concerned about accidentally generating "dirty" words, try
Consonant-consonant-vowel-digit
Consonant-consonant-vowel-digit
This lessens the odds.
| [reply] |
(dkubb) Re: (2) Random Text: There's got to be an easier way
by dkubb (Deacon) on Jun 03, 2001 at 23:28 UTC
|
Here's another way to generate an 8 character string, containing
characters in the ranges 2-9 and a-z, using the CPAN module
String::Random:
#!/usr/bin/perl -w
use strict;
use String::Random;
my $string_random = String::Random->new;
print $string_random->randregex('[a-z2-9]' x 8);
| [reply] [d/l] |
Re: Random Text: There's got to be an easier way
by John M. Dlugosz (Monsignor) on Jun 03, 2001 at 22:02 UTC
|
I've done something similar for ID numbers. It is indeed a little shorter:
my $length= 6; #how many digits to generate
my @letters= split (//, '0123456789abcdefghijkmnopqrstuvwxyz');
sub create_new_ID
{
my $result;
foreach my $iteration (1..$length) {
$result .= $letters[int(rand(scalar @letters))];
}
return $result;
}
I didn't use the dotdot in the list constructor, as you see. I think you could have written 'a'..'z' (that is, use the quotes) and not get the bareword warning. However, note that I leave out 'l' because it looks too much like a '1', and it should be somewhat human readable/reproducable, right?
—John | [reply] [d/l] |
|
I didn't use the dotdot in the list constructor, as you see. I think you could have written 'a'..'z' (that is, use the quotes) and not get the bareword warning. However, note that I leave out 'l' because it looks too much like a '1', and it should be somewhat human readable/reproducable, right?
human readable code is good too :
my @letters= ("a".."k","m".."z","2".."9");
| [reply] [d/l] |
Re: Random Text: There's got to be an easier way
by shotgunefx (Parson) on Jun 03, 2001 at 22:23 UTC
|
You may want to do a check for profanity. I know of one company who uses letters and numbers who's system generated at least a few orders with the word f*ck in it.
This suprisingly enough offended some. ;)
Actually excluding u will take care of most naughty words.
-Lee
"To be civilized is to deny one's nature." | [reply] |
|
exclude u: nice idea. I don't like the idea of putting naughty words into the script for filtering purposes! A simple way of not generating them in the first place is elegant.
| [reply] |
|
seems to me that removing "u" won't actually solve the problem very well, but removing all vowels should do the trick. then again, if your users are particularly sensitive, they may be bothered by "fck" on its own.
| [reply] |
|
|
Re: Random Text: There's got to be an easier way
by thpfft (Chaplain) on Jun 03, 2001 at 21:14 UTC
|
$ENV{UNIQUE_ID} is usually available if you're on apache. It looks something like 'OxpuVdRDyd0AABcZKVw', so it isn't all that readable, but it's certainly an easier way.
(nb this is no use at all if you need to create more than one id per script invocation)
see the apache docs for more.
| [reply] [d/l] |
|
$ENV{UNIQUE_ID} depends on the presence of mod_unique_id. I know I always include it in the build, but does everyone? :)
Also note that Perl isn't always used as CGI. mod_unique_id is an Apache thing :)
Greetz
Beatnik
... Quidquid perl dictum sit, altum viditur.
| [reply] [d/l] |
Re: Random Text: There's got to be an easier way
by CharlesClarkson (Curate) on Jun 04, 2001 at 09:08 UTC
|
my $rand;
$rand .= ('a' .. 'z', 2 ..9)[rand 34] foreach 0 .. 7;
print $rand;
HTH,
Charles K. Clarkson
| [reply] [d/l] |
Re: Random Text: There's got to be an easier way
by dvergin (Monsignor) on Jun 04, 2001 at 10:38 UTC
|
Or generalize as a general-purpose routine so
you don't have to write another one next time:
sub make_rand_str {
# e.g.: $str = make_rand_str(8, 'A'..'Z','2'..'9');
my ($num_chars, @possible_chr_array) = @_;
my $num_possibles = @possible_chr_array;
my $rnd_str = "";
for (1..$num_chars) {
$rnd_str .= $possible_chr_array[rand($num_possibles)];
}
return $rnd_str;
}
| [reply] [d/l] |