File Coverage

File:bin/random-string
Coverage:96.2%

linestmtbrancondsubtimecode
1#!/usr/bin/env perl
2
3
23
23
23
42609
17
351
use strict;
4
23
23
23
32
13
494
use warnings;
5
23
23
23
7119
106305
36
use Getopt::Long qw(:config no_ignore_case);
6
23
23
23
6638
595281
1091
use Pod::Usage;
7
23
23
23
4930
26
16138
use Data::Random::String::Matches;
8
9
23
1233253
our $VERSION = '0.02';
10
11# Parse command line options
12
23
77
my %opts = (
13        count     => 1,
14        length   => undef,
15        smart     => 0,
16        unique   => 0,
17        separator  => "\n",
18        help       => 0,
19        man             => 0,
20        version => 0,
21        examples   => 0,
22);
23
24GetOptions(
25        'count|c=i'      => \$opts{count},
26        'length|l=i'    => \$opts{length},
27        'smart|s'          => \$opts{smart},
28        'unique|u'        => \$opts{unique},
29        'separator|S=s' => \$opts{separator},
30        'help|h|?'        => \$opts{help},
31        'man|m'          => \$opts{man},
32        'version|v'      => \$opts{version},
33        'examples|e'    => \$opts{examples},
34
23
76
) or pod2usage(2);
35
36# Handle special options
37
23
10471
if ($opts{version}) {
38
1
3
        print "random-string version $VERSION\n";
39
1
0
        exit 0;
40}
41
42
22
28
pod2usage(1) if $opts{help};
43
21
22
pod2usage(-exitval => 0, -verbose => 2) if $opts{man};
44
45
20
22
if ($opts{examples}) {
46
1
1
        show_examples();
47
1
0
        exit 0;
48}
49
50# Get the pattern from command line
51
19
40
my $pattern = shift @ARGV;
52
53
19
29
unless (defined $pattern) {
54
2
56
        print STDERR "Error: Pattern required\n\n";
55
2
4
        pod2usage(1);
56}
57
58# Validate options
59
17
36
if ($opts{count} < 1) {
60
1
9
        die 'Error: count must be at least 1';
61}
62
63# Decode escape sequences in separator
64
16
25
$opts{separator} =~ s/\\n/\n/g;
65
16
12
$opts{separator} =~ s/\\t/\t/g;
66
16
15
$opts{separator} =~ s/\\r/\r/g;
67
16
16
$opts{separator} =~ s/\\0/\0/g;
68
69# Create generator
70
16
8
my $gen = eval {
71
16
76
        Data::Random::String::Matches->new($pattern, $opts{length});
72};
73
74
16
16
if ($@) {
75
0
0
        die "Error creating generator: $@";
76}
77
78# Generate strings
79
16
10
my @results;
80
16
25
for (1 .. $opts{count}) {
81
25
15
        my $str = eval {
82
25
40
                $opts{smart} ? $gen->generate_smart() : $gen->generate();
83        };
84
85
25
278
        if ($@) {
86
1
3
                die "Error generating string: $@";
87        }
88
89
24
40
        push @results, $str;
90}
91
92# Output results
93
15
71
print join($opts{separator}, @results);
94
15
28
print "\n" unless $opts{separator} =~ /\n$/;
95
96
15
0
exit 0;
97
98sub show_examples {
99
1
2
        print <<'EXAMPLES';
100Examples:
101
102  # Generate a single 4-digit number
103  random-string '\d{4}'
104
105  # Generate 10 API keys
106  random-string 'AIza[0-9A-Za-z_-]{35}' --count 10
107
108  # Generate 5 email addresses
109  random-string '[a-z]{5,10}@[a-z]{5,10}\.com' -c 5
110
111  # Generate phone numbers with custom separator
112  random-string '\d{3}-\d{3}-\d{4}' -c 3 -S ', '
113
114  # Generate uppercase letters (3 characters)
115  random-string '[A-Z]{3}'
116
117  # Generate password-like strings
118  random-string '[A-Za-z0-9!@#$%]{16}' -c 5
119
120  # Generate UUID-like strings
121  random-string '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
122
123  # Use alternation
124  random-string '(cat|dog|bird)' -c 10
125
126  # Use backreferences (repeating pattern)
127  random-string '(\w{3})-\1' -c 5
128
129  # Generate credit card test numbers
130  random-string '4\d{15}' -c 3
131
132  # Use smart mode for complex patterns (faster)
133  random-string '[A-Z]{3}\d{4}' -c 100 --smart
134
135Common patterns:
136  \d{4}                                 - 4-digit PIN
137  [A-Z]{2}\d{3}                 - License plate style
138  \d{3}-\d{3}-\d{4}             - Phone number
139  [a-z]+@[a-z]+\.com       - Simple email
140  [A-Fa-f0-9]{32}                 - MD5 hash
141  [A-Za-z0-9]{20}                 - Random token
142  (foo|bar|baz)                 - One of three options
143  (\w{4})-\1                       - Repeated pattern
144
145EXAMPLES
146}
147