1################################################################################
2# Data::Random
3#
4# A module used to generate random data.
5################################################################################
6
7package Data::Random;
8
9################################################################################
10# - Modules and Libraries
11################################################################################
12use strict;
13use warnings;
14use 5.005_62;
15
16use Carp qw(cluck);
17use Time::Piece;
18#use Data::Random::WordList;
19
20require Exporter;
21
22################################################################################
23# - Global Constants and Variables
24################################################################################
25use vars qw(
26  @ISA
27  %EXPORT_TAGS
28  @EXPORT_OK
29  @EXPORT
30);
31
32@ISA = qw(Exporter);
33
34%EXPORT_TAGS = (
35    'all' => [
36        qw(
37        rand_words
38        rand_chars
39        rand_set
40        rand_enum
41        rand_date
42        rand_time
43        rand_datetime
44        rand_image
45        )
46    ]
47);
48
49@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
50@EXPORT    = qw();
51
52our $VERSION = '0.13';
53
54################################################################################
55# - Subroutines
56################################################################################
57
58################################################################################
59# rand_words()
60################################################################################
61sub rand_words {
62
63    # Get the options hash
64    my %options = @_;
65
66    # Initialize max and min vars
67    $options{'min'} ||= 1;
68    $options{'max'} ||= 1;
69
70    # Initialize the wordlist param
71    $options{'wordlist'} ||= '';
72
73    # Make sure the max and min vars are OK
74    cluck('min value cannot be larger than max value') && return
75      if $options{'min'} > $options{'max'};
76    cluck('min value must be a positive integer') && return
77      if $options{'min'} < 0 || $options{'min'} != int( $options{'min'} );
78    cluck('max value must be a positive integer') && return
79      if $options{'max'} < 0 || $options{'max'} != int( $options{'max'} );
80
81    # Initialize the size var
82    $options{'size'} ||=
83      int( rand( $options{'max'} - $options{'min'} + 1 ) ) + $options{'min'};
84
85    # Make sure the size var is OK
86    cluck('size value must be a positive integer') && return
87      if $options{'size'} < 0 || $options{'size'} != int( $options{'size'} );
88
89    # Initialize the shuffle flag
90    $options{'shuffle'} =
91      exists( $options{'shuffle'} ) ? $options{'shuffle'} : 1;
92
93    my $wl;
94    my $close_wl = 1;
95
96    # Check for a pre-existing wordlist object
97    if ( ref( $options{'wordlist'} ) ) {
98        $wl       = $options{'wordlist'};
99        $close_wl = 0;
100    }
101    else {
102        require Data::Random::WordList;
103
104        # Create a new wordlist object
105        $wl = Data::Random::WordList->new( wordlist => $options{'wordlist'} );
106    }
107
108    # Get the random words
109    my $rand_words = $wl->get_words( $options{'size'} );
110
111    # Close the word list
112    $wl->close() if $close_wl;
113
114    # Shuffle the words around
115    _shuffle($rand_words) if $options{'shuffle'};
116
117# Return an array or an array reference, depending on the context in which the sub was called
118    if ( wantarray() ) {
119        return @$rand_words;
120    }
121    else {
122        return $rand_words;
123    }
124}
125
126################################################################################
127# rand_chars()
128################################################################################
129sub rand_chars {
130
131    # Get the options hash
132    my %options = @_;
133    my @chars;
134
135    # Build named character sets if one wasn't supplied
136    if ( ref( $options{'set'} ) ne 'ARRAY' ) {
137        my @charset = ();
138
139        if ( $options{'set'} eq 'all' ) {
140            @charset =
141              ( 0 .. 9, 'a' .. 'z', 'A' .. 'Z', '#', ',',
142                qw(~ ! @ $ % ^ & * ( ) _ + = - { } | : " < > ? / . ' ; ] [ \ `)
143            );
144        }
145        elsif ( $options{'set'} eq 'alpha' ) {
146            @charset = ( 'a' .. 'z', 'A' .. 'Z' );
147        }
148        elsif ( $options{'set'} eq 'upperalpha' ) {
149            @charset = ( 'A' .. 'Z' );
150        }
151        elsif ( $options{'set'} eq 'loweralpha' ) {
152            @charset = ( 'a' .. 'z' );
153        }
154        elsif ( $options{'set'} eq 'numeric' ) {
155            @charset = ( 0 .. 9 );
156        }
157        elsif ( $options{'set'} eq 'alphanumeric' ) {
158            @charset = ( 0 .. 9, 'a' .. 'z', 'A' .. 'Z' );
159        }
160        elsif ( $options{'set'} =~ /^(misc|char)$/ ) {
161            @charset =
162              ( '#', ',',
163                qw(~ ! @ $ % ^ & * ( ) _ + = - { } | : " < > ? / . ' ; ] [ \ `)
164            );
165        }
166
167        $options{'set'} = \@charset;
168    }
169
170    @chars = rand_set(%options);
171    return wantarray ? @chars : join('', @chars);
172}
173
174################################################################################
175# rand_set()
176################################################################################
177sub rand_set {
178
179    # Get the options hash
180    my %options = @_;
181
182    # Make sure the set array was defined
183    cluck('set array is not defined') && return if !$options{'set'};
184
185    $options{'size'} = 1
186      unless exists( $options{'min'} ) || exists( $options{'max'} )
187      || exists( $options{'size'} );
188
189    # Initialize max and min vars
190    $options{'min'} ||= 0;
191    $options{'max'} ||= @{ $options{'set'} };
192
193    # Make sure the max and min vars are OK
194    cluck('min value cannot be larger than max value') && return
195      if $options{'min'} > $options{'max'};
196    cluck('min value must be a positive integer') && return
197      if $options{'min'} < 0 || $options{'min'} != int( $options{'min'} );
198    cluck('max value must be a positive integer') && return
199      if $options{'max'} < 0 || $options{'max'} != int( $options{'max'} );
200
201    # Initialize the size var
202    $options{'size'} ||=
203      int( rand( $options{'max'} - $options{'min'} + 1 ) ) + $options{'min'};
204
205    # Make sure the size var is OK
206    cluck('size value must be a positive integer') && return
207      if $options{'size'} < 0 || $options{'size'} != int( $options{'size'} );
208    cluck('size value exceeds set size') && return
209      if $options{'size'} > @{ $options{'set'} };
210
211    # Initialize the shuffle flag
212    $options{'shuffle'} =
213      exists( $options{'shuffle'} ) ? $options{'shuffle'} : 1;
214
215    # Get the random items
216    my %results = ();
217    for ( my $i = 0 ; $i < $options{'size'} ; $i++ ) {
218        my $result;
219
220        do {
221            $result = int( rand( @{ $options{'set'} } ) );
222        } while ( exists( $results{$result} ) );
223
224        $results{$result} = 1;
225    }
226
227    my @results = sort { $a <=> $b } keys %results;
228
229    # Shuffle the items
230    _shuffle( \@results ) if $options{'shuffle'};
231
232# Return an array or an array reference, depending on the context in which the sub was called
233    if ( wantarray() ) {
234        return @{ $options{'set'} }[@results];
235    }
236    else {
237        return \@{ $options{'set'} }[@results];
238    }
239}
240
241################################################################################
242# rand_enum()
243################################################################################
244sub rand_enum {
245
246    # Get the options hash
247    my %options = @_ == 1 && ref $_[0] eq 'ARRAY' ? ( set => @_ ) : @_;
248
249    # Make sure the set array was defined
250    cluck('set array is not defined') && return if !$options{'set'};
251
252    return $options{'set'}->[ int( rand( @{ $options{'set'} } ) ) ];
253}
254
255################################################################################
256# rand_date()
257################################################################################
258sub rand_date {
259
260    # Get the options hash
261    my %options = @_;
262
263    my $min;
264    my $max;
265    # Get today's date
266    my $t = localtime;
267    my ( $year, $month, $day ) = split('-', $t->ymd);
268    my $today = Time::Piece->strptime($t->ymd, "%Y-%m-%d");
269
270    if ( $options{'min'} ) {
271        if ( $options{'min'} eq 'now' ) {
272            $min = $today;
273        }
274        else {
275            $min = Time::Piece->strptime($options{'min'}, '%Y-%m-%d');
276        }
277    }
278    else {
279        $min = $today;
280    }
281    if ( $options{'max'} ) {
282        if ( $options{'max'} eq 'now' ) {
283            $max = $today;
284        }
285        else {
286            $max = Time::Piece->strptime($options{max}, "%Y-%m-%d");
287        }
288    }
289    else {
290          $max = $min->add_years(1);
291    }
292
293    my $delta_days = int($max->julian_day) - int($min->julian_day);
294    cluck('max date is later than min date') && return if $delta_days < 0;
295
296    my $result = $min + ( 3600 * 24  * int( rand($delta_days + 1) ) );
297    return $result->ymd;
298}
299
300################################################################################
301# rand_time()
302################################################################################
303sub rand_time {
304
305    # Get the options hash
306    my %options = @_;
307
308    my ( $min_hour, $min_min, $min_sec, $max_hour, $max_min, $max_sec );
309
310    if ( $options{'min'} ) {
311        if ( $options{'min'} eq 'now' ) {
312
313            # Get the current time
314            my ( $hour, $min, $sec ) = ( localtime() )[ 2, 1, 0 ];
315
316            ( $min_hour, $min_min, $min_sec ) = ( $hour, $min, $sec );
317        }
318        else {
319            eval {
320                my $min = Time::Piece->strptime( $options{min}, '%T' );
321                ( $min_hour, $min_min, $min_sec )
322                    = ( $min->hour, $min->min, $min->sec );
323            };
324            if ($@) {
325                cluck 'minimum time is not in valid time format HH:MM:SS';
326                return;
327            }
328        }
329    }
330    else {
331        ( $min_hour, $min_min, $min_sec ) = ( 0, 0, 0 );
332    }
333
334    if ( $options{'max'} ) {
335        if ( $options{'max'} eq 'now' ) {
336
337            # Get the current time
338            my ( $hour, $min, $sec ) = ( localtime() )[ 2, 1, 0 ];
339
340            ( $max_hour, $max_min, $max_sec ) = ( $hour, $min, $sec );
341        }
342        else {
343            eval {
344                my $max = Time::Piece->strptime( $options{max}, '%T' );
345                ( $max_hour, $max_min, $max_sec )
346                    = ( $max->hour, $max->min, $max->sec );
347            };
348            if ($@) {
349                cluck 'maximum time is not in valid time format HH:MM:SS';
350                return;
351            }
352        }
353    }
354    else {
355        ( $max_hour, $max_min, $max_sec ) = ( 23, 59, 59 );
356    }
357
358    my $min_secs = $min_hour * 3600 + $min_min * 60 + $min_sec;
359    my $max_secs = ( $max_hour * 3600 ) + ( $max_min * 60 ) + $max_sec;
360
361    my $delta_secs = $max_secs - $min_secs;
362
363    cluck('min time is later than max time') && return if $delta_secs < 0;
364
365    $delta_secs = int( rand( $delta_secs + 1 ) );
366
367    my $result_secs = $min_secs + $delta_secs;
368
369    my $hour = int( $result_secs / 3600 );
370    my $min  = int( ( $result_secs - ( $hour * 3600 ) ) / 60 );
371    my $sec  = $result_secs % 60;
372
373    return sprintf( "%02u:%02u:%02u", $hour, $min, $sec );
374}
375
376################################################################################
377# rand_datetime()
378################################################################################
379sub rand_datetime {
380
381    # Get the options hash
382    my %options = @_;
383
384    # Get today's date
385    my $now = localtime;
386    my $minimum;
387    my $maximum;
388
389    if ( $options{min} ) {
390        if ( $options{min} eq 'now' ) {
391            $minimum = Time::Piece->strptime(
392              $now->strftime('%Y-%m-%d %H:%M:%S'),
393              '%Y-%m-%d %H:%M:%S'
394            );
395        }
396        else {
397            $minimum = Time::Piece->strptime(
398              $options{min},
399              '%Y-%m-%d %H:%M:%S'
400            );
401        }
402    }
403    else {
404        $minimum = $now;
405    }
406
407    if ( $options{max} ) {
408        if ( $options{max} eq 'now' ) {
409            $maximum = Time::Piece->strptime(
410              $now->strftime('%Y-%m-%d %H:%M:%S'),
411              '%Y-%m-%d %H:%M:%S'
412            );
413        }
414        else {
415            $maximum = Time::Piece->strptime(
416              $options{max},
417              '%Y-%m-%d %H:%M:%S'
418            );
419        }
420    }
421    else {
422        $maximum = $minimum->add_years(1);
423    }
424
425    my $delta_secs = $maximum - $minimum;
426    cluck('max_date is later than min date') && return if $delta_secs < 0;
427    $delta_secs = int( rand( $delta_secs + 1 ) );
428
429    my $result = $minimum + $delta_secs;
430
431    return $result->strftime('%Y-%m-%d %H:%M:%S');
432}
433
434################################################################################
435# rand_image()
436################################################################################
437sub rand_image {
438
439    # Get the options hash
440    my %options = @_;
441
442    eval q{ require GD; };
443    cluck($@) && return if $@;
444
445    $options{'minwidth'} ||= 1;
446    $options{'maxwidth'} ||= 100;
447    $options{'width'} ||=
448      int( rand( $options{'maxwidth'} - $options{'minwidth'} + 1 ) ) +
449      $options{'minwidth'};
450
451    $options{'minheight'} ||= 1;
452    $options{'maxheight'} ||= 100;
453    $options{'height'} ||=
454      int( rand( $options{'maxheight'} - $options{'minheight'} + 1 ) ) +
455      $options{'minheight'};
456
457    $options{'minpixels'} ||= 0;
458    $options{'maxpixels'} ||= $options{'width'} * $options{'height'};
459    $options{'pixels'} ||=
460      int( rand( $options{'maxpixels'} - $options{'minpixels'} + 1 ) ) +
461      $options{'minpixels'};
462
463    $options{'bgcolor'} ||= _color();
464    $options{'fgcolor'} ||= _color();
465
466    my $image = GD::Image->new( $options{'width'}, $options{'height'} );
467
468    my $bgcolor = $image->colorAllocate( @{ $options{'bgcolor'} } );
469    my $fgcolor = $image->colorAllocate( @{ $options{'fgcolor'} } );
470
471    $image->rectangle( 0, 0, $options{'width'}, $options{'height'}, $bgcolor );
472
473    for ( my $i = 0 ; $i < $options{'pixels'} ; $i++ ) {
474        my $x = int( rand( $options{'width'} + 1 ) );
475        my $y = int( rand( $options{'height'} + 1 ) );
476
477        $image->setPixel( $x, $y, $fgcolor );
478    }
479
480    return $image->png();
481
482    sub _color {
483        return [ int( rand(256) ), int( rand(256) ), int( rand(256) ) ];
484    }
485}
486
487################################################################################
488# _shuffle()
489################################################################################
490sub _shuffle {
491    my $array = shift;
492
493    for ( my $i = @$array - 1 ; $i >= 0 ; $i-- ) {
494        my $j = int( rand( $i + 1 ) );
495
496        @$array[ $i, $j ] = @$array[ $j, $i ] if $i != $j;
497    }
498}
499
5001;
501
502
503
504=head1 NAME
505
506Data::Random - Perl module to generate random data
507
508
509=head1 SYNOPSIS
510
511  use Data::Random qw(:all);
512
513  my @random_words = rand_words( size => 10 );
514
515  my @random_chars = rand_chars( set => 'all', min => 5, max => 8 );
516  my $string       = rand_chars( set => 'all', min => 5, max => 8 );
517
518  my @random_set = rand_set( set => \@set, size => 5 );
519
520  my $random_enum = rand_enum( set => \@set );
521  my $random_enum = rand_enum( \@set ); # shortcut
522
523  my $random_date = rand_date();
524
525  my $random_time = rand_time();
526
527  my $random_datetime = rand_datetime();
528
529  open(my $file, ">", "rand_image.png") or die $!;
530  binmode($file);
531  print $file rand_image( bgcolor => [0, 0, 0] );
532  close($file);
533
534
535=head1 DESCRIPTION
536
537A module used to generate random data.  Useful mostly for test programs.
538
539
540=head1 METHODS
541
542=head2 rand_words()
543
544This returns a list of random words given a wordlist.  See below for possible parameters.
545
546=over 4
547
548=item *
549
550wordlist - the path to the wordlist file.  A lot of systems have one at /usr/dict/words.  You can also optionally supply a Data::Random::WordList object to keep a persistent wordlist.  The default is the wordlist distributed with this module.
551
552=item *
553
554min - the minimum number of words to return.  The default is 1.
555
556=item *
557
558max - the maximum number of words to return.  The default is 1.
559
560=item *
561
562size - the number of words to return.  The default is 1.  If you supply a value for 'size', then 'min' and 'max' aren't paid attention to.
563
564=item *
565
566shuffle - whether or not the words should be randomly shuffled.  Set this to 0 if you don't want the words shuffled.  The default is 1.  Random::Data::WordList returns words in the order that they're viewed in the word list file, so shuffling will make sure that the results are a little more random.
567
568=back
569
570
571=head2 rand_chars()
572
573When called in a list context this returns
574a list of random characters given a set of characters.
575In a scalar context it returns a string of random characters.
576See below for possible parameters.
577
578=over 4
579
580=item *
581
582set - the set of characters to be used.  This value can be either a reference to an array of strings, or one of the following:
583
584    alpha        - alphabetic characters: a-z, A-Z
585    upperalpha   - upper case alphabetic characters: A-Z
586    loweralpha   - lower case alphabetic characters: a-z
587    numeric      - numeric characters: 0-9
588    alphanumeric - alphanumeric characters: a-z, A-Z, 0-9
589    char         - non-alphanumeric characters: # ~ ! @ $ % ^ & * ( ) _ + = - { } | : " < > ? / . ' ; ] [ \ `
590    misc         - same as 'char'
591    all          - all of the above
592
593=item *
594
595min - the minimum number of characters to return.  The default is 0.
596
597=item *
598
599max - the maximum number of characters to return.  The default is the size of the set.
600
601=item *
602
603size - the number of characters to return.  The default is 1.  If you supply a value for 'size', then 'min' and 'max' aren't paid attention to.
604
605=item *
606
607shuffle - whether or not the characters should be randomly shuffled.  Set this to 0 if you want the characters to stay in the order received.  The default is 1.
608
609=back
610
611
612=head2 rand_set()
613
614This returns a random set of elements given an initial set.  See below for possible parameters.
615
616=over 4
617
618=item *
619
620set - the set of strings to be used.  This should be a reference to an array of strings.
621
622=item *
623
624min - the minimum number of strings to return.  The default is 0.
625
626=item *
627
628max - the maximum number of strings to return.  The default is the size of the set.
629
630=item *
631
632size - the number of strings to return.  The default is 1.  If you supply a value for 'size', then 'min' and 'max' aren't paid attention to.
633
634=item *
635
636shuffle - whether or not the strings should be randomly shuffled.  Set this to 0 if you want the strings to stay in the order received.  The default is 1.
637
638=back
639
640
641=head2 rand_enum()
642
643This returns a random element given an initial set.  See below for possible parameters.
644
645=over 4
646
647=item *
648
649set - the set of strings to be used.  This should be a reference to an array of strings. The C<set> key will be assumed if the array reference is passed as the only argument.
650
651=back
652
653
654=head2 rand_date()
655
656This returns a random date in the form "YYYY-MM-DD".  2-digit years are not currently supported.  Efforts are made to make sure you're returned a truly valid date--ie, you'll never be returned the date February 31st.  See the options below to find out how to control the date range.  Here are a few examples:
657
658    # returns a date somewhere in between the current date, and one year from the current date
659    $date = rand_date();
660
661    # returns a date somewhere in between September 21, 1978 and September 21, 1979
662    $date = rand_date( min => '1978-9-21' );
663
664    # returns a date somewhere in between September 21, 1978 and the current date
665    $date = rand_date( min => '1978-9-21', max => 'now' );
666
667    # returns a date somewhere in between the current date and September 21, 2008
668    $date = rand_date( min => 'now', max => '2008-9-21' );
669
670See below for possible parameters.
671
672=over 4
673
674=item *
675
676min - the minimum date to be returned. It should be in the form "YYYY-MM-DD" or you can alternatively use the string "now" to represent the current date.  The default is the current date;
677
678=item *
679
680max - the maximum date to be returned. It should be in the form "YYYY-MM-DD" or you can alternatively use the string "now" to represent the current date.  The default is one year from the minimum date;
681
682=back
683
684
685=head2 rand_time()
686
687This returns a random time in the form "HH:MM:SS".  24 hour times are supported.  See the options below to find out how to control the time range.  Here are a few examples:
688
689    # returns a random 24-hr time (between 00:00:00 and 23:59:59)
690    $time = rand_time();
691
692    # returns a time somewhere in between 04:00:00 and the end of the day
693    $time = rand_time( min => '4:0:0' );
694
695    # returns a time somewhere in between 8:00:00 and the current time (if it's after 8:00)
696    $time = rand_time( min => '12:00:00', max => 'now' );
697
698    # returns a date somewhere in between the current time and the end of the day
699    $time = rand_time( min => 'now' );
700
701See below for possible parameters.
702
703=over 4
704
705=item *
706
707min - the minimum time to be returned. It should be in the form "HH:MM:SS" or you can alternatively use the string "now" to represent the current time.  The default is 00:00:00;
708
709=item *
710
711max - the maximum time to be returned. It should be in the form "HH:MM:SS" or you can alternatively use the string "now" to represent the current time.  The default is 23:59:59;
712
713=back
714
715
716=head2 rand_datetime()
717
718This returns a random date and time in the form "YYYY-MM-DD HH:MM:SS".  See the options below to find out how to control the date/time range.  Here are a few examples:
719
720    # returns a date somewhere in between the current date/time, and one year from the current date/time
721    $datetime = rand_datetime();
722
723    # returns a date somewhere in between 4:00 September 21, 1978 and 4:00 September 21, 1979
724    $datetime = rand_datetime( min => '1978-9-21 4:0:0' );
725
726    # returns a date somewhere in between 4:00 September 21, 1978 and the current date
727    $datetime = rand_datetime( min => '1978-9-21 4:0:0', max => 'now' );
728
729    # returns a date somewhere in between the current date/time and the end of the day September 21, 2008
730    $datetime = rand_datetime( min => 'now', max => '2008-9-21 23:59:59' );
731
732See below for possible parameters.
733
734=over 4
735
736=item *
737
738min - the minimum date/time to be returned. It should be in the form "YYYY-MM-DD HH:MM:SS" or you can alternatively use the string "now" to represent the current date/time.  The default is the current date/time;
739
740=item *
741
742max - the maximum date/time to be returned. It should be in the form "YYYY-MM-DD HH:MM:SS" or you can alternatively use the string "now" to represent the current date/time.  The default is one year from the minimum date/time;
743
744=back
745
746
747=head2 rand_image()
748
749This returns a random image.  Currently only PNG images are supported.  See below for possible parameters.
750
751=over 4
752
753=item *
754
755minwidth - the minimum width of the image.  The default is 1.
756
757=item *
758
759maxwidth - the maximum width of the image.  The default is 100.
760
761=item *
762
763width - the width of the image.  If you supply a value for 'width', then 'minwidth' and 'maxwidth' aren't paid attention to.
764
765=item *
766
767minheight - the minimum height of the image.  The default is 1.
768
769=item *
770
771maxheight - the maximum height of the image.  The default is 100.
772
773=item *
774
775height - the height of the image.  If you supply a value for 'width', then 'minwidth' and 'maxwidth' aren't paid attention to.
776
777=item *
778
779minpixels - the minimum number of random pixels to display on the image.  The default is 0.
780
781=item *
782
783maxpixels - the maximum number of random pixels to display on the image.  The default is width * height.
784
785=item *
786
787pixels - the number of random pixels to display on the image.  If you supply a value for 'pixels', then 'minpixels' and 'maxpixels' aren't paid attention to.
788
789=item *
790
791bgcolor - the background color of the image.  The value must be a reference to an RGB array where each element is an integer between 0 and 255 (eg. [ 55, 120, 255 ]).
792
793=item *
794
795fgcolor - the foreground color of the image.  The value must be a reference to an RGB array where each element is an integer between 0 and 255 (eg. [ 55, 120, 255 ]).
796
797=back
798
799
800=head1 VERSION
801
8020.12
803
804
805=head1 AUTHOR
806
807Originally written by: Adekunle Olonoh
808
809Currently maintained by: Buddy Burden (barefoot@cpan.org), starting with version 0.06
810
811
812=head1 CREDITS
813
814    Hiroki Chalfant
815    David Sarno
816	Michiel Beijen
817
818
819=head1 COPYRIGHT
820
821Copyright (c) 2000-2011 Adekunle Olonoh.
822Copyright (c) 2011-2015 Buddy Burden.
823All rights reserved.  This program is free software; you
824can redistribute it and/or modify it under the same terms as Perl itself.
825
826
827=head1 SEE ALSO
828
829L<Data::Random::WordList>
830
831=cut
832