#!/usr/bin/env perl #program to generate 6 Million unique codes, Oct 15, 2011. use strict; use warnings; use autodie; use v5.10; # Just for feature "say" # Some criteria. my @digits_used = ( 'a' .. 'z', 3, 4, 6, 7, 9 ); my $string_length = 10; my $need = 6_000_000; my $filename = 'testfile.txt'; # Takes a string length, and a list of digits allowed, and returns an # iterator function that on each call returns a unique string. sub create_random_string_generator { # Our bind values: my $size = shift; my @contains = @_; # Our duplicate cache. my %found; # Here's where we create an iterator function with bound criteria. return sub { my $rand_string; do{ my @rand_digits; push @rand_digits, $contains[ rand @contains ] for 1 .. $size; $rand_string = join '', @rand_digits; } while( $found{$rand_string}++ ); return $rand_string; } } # Now we bind our criteria and create a generator iterator function. my $string_gen = create_random_string_generator( $string_length, @digits_used ); open my $out_fh, '>', $filename; for( my $count = 0; $count < $need; $count++ ) { say $out_fh $string_gen->(); } close $out_fh; #### # Verify that there are no duplicates. perl -nE 'say $_ if $seen{$_}++;' testfile.txt # We want no output. # Verify that there are 6000000 lines. perl -nE '$count++; END{ say $count; }' testfile.txt # We want 6000000 as the output. # Verify that we only have digits between a..z and 3, 4, 6, 7, 9. perl -nE 'say "$. : $_" if m/[^a-z34679\n]/' testfile.txt # We want no output. #### package CodeGenerator; use strict; use warnings; sub new { my $class = shift; my $self = bless {}, $class; $self->{string_size} = shift; $self->{digits_used} = [ @_ ]; $self->{seen} = {}; # Not necessary, but helpful to # those reading the code. return $self; } sub generate { my $self = shift; my $rand_string; do{ $rand_string = ''; $rand_string .= $self->{digits_used}[ rand @{$self->{digits_used}} ] for 1 .. $self->{string_size}; } while( $self->{seen}{$rand_string}++ ); return $rand_string; } 1; package main; use strict; use warnings; use autodie; use v5.10; # For "say". # Some criteria. my @digits_used = ( 'a' .. 'z', 3, 4, 6, 7, 9 ); my $string_length = 10; my $need = 6_000_000; my $filename = 'testfile.txt'; my $codegen = CodeGenerator->new( $string_length, @digits_used ); open my $out_fh, '>', $filename; for( my $count = 0; $count < $need; $count++ ) { say $out_fh $codegen->generate(); } close $out_fh;