Need specialized random string generator script

Hi,
I need a script that will generate a set of random strings in sequence, with the ability to predetermine the length, quantity, and alphabet of individual string, and to use the outputs of earlier strings in the sequence to define the parameters of later strings. For examples, I might want to generate a one-character string with an alphabet of {1,2,3,4}, followed by X one-character strings with the alphabet {0,1}, where X equals the output of the first string. Unfortunately I don't know too much about code -- I'm not a programmer, this is for a sociolinguistics project -- but if anyone has any relatively easy ideas as to how to make this happen I'd much appreciate it.

Thanks
V

If you don't know much about code, I'm not sure how helpful this forum will
be to you.

Having said that, you can play around with this and adjust MINIMUM_LEN
and MAXIMUM_LEN to suit your needs.

cat random_password.ksh
#!/bin/ksh
mkrandpwd()
{
let MINIMUM_LEN=5
let MAXIMUM_LEN=20
#### 
#### Set the array of valid characters to be all upper and
#### lower case letters, all digits, and a selected set of
#### punctuation symbols.
#### 

set -A CHARS a b c d e f g h i j k l m n o p q r s t u v w x y z \
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
0 1 2 3 4 5 6 7 8 9 \; \: \. \~ \! \@ \# \$ \% \^ \& \* - + = \? 

CNUM="${#CHARS[@]}"

################################################################

#### Calculate a random length for the random password string between the
#### MINIMUM_LEN and MAXIMUM_LEN values provided
#### 
MAXLEN=$(( $MINIMUM_LEN + ( $RANDOM % ( $MAXIMUM_LEN - $MINIMUM_LEN ) ) ))

#### 
#### extract a random character from the CHARS array for each position
#### of the random password string. The length of the random string 
#### determined by the MAXLEN variable.
#### 
RANDSTR=""
let POSCNT=0; 
while [ 1 -eq 1 ] 
do
if [ $POSCNT -ge $MAXLEN ]
then
break;
fi
let POSCNT=$POSCNT+1
#### 
#### Using the modulo of a random number divided by the number of 
#### characters (array elements) in the CHARS array, provides a
#### random array element position. The random array element position
#### is used to append a single character at a time from the CHARS array
#### onto the random password string variable RANDSTR.
#### 
RANDSTR="${RANDSTR}${CHARS[${RANDOM}%${CNUM}]}"
done

echo "password=${RANDSTR} length=${MAXLEN}"
return 0
}
mkrandpwd 

Here is some some sample output:

password=KBIJAuEBax0JciX           length=15
password=e+JUKKO9TJPCQ%.G     length=16
password=ZSJ5V7Qrl                    length=9
password=-;Kk+C2hE3z+hoLKH-    length=18
1 Like

Hi.

What would you design for such a script if you could? Would you have parameters on the control statement, in a file, what? Would you use xxx=yyy for most things?

In short, sketch what you are really looking for -- not the internals -- just the user interface ... cheers, drl

This does what you asked for (based on BeefStu's great starter).

#!/bin/ksh
genstr()
{
    # generate a readom string contaning n characters from a supplied
    # list of chars
    #
    # usage: genstr <n> <listchar ...>
    #
    # eg:  genstr 8 0 1 would generate an 8 digit binary number
    #
    LEN=$1
    shift
    set -A CHARS $@
    CNUM="${#CHARS[@]}"
    RANDSTR=""
    let POSCNT=0;
    while true
    do
        [ $POSCNT -ge $LEN ] && break;
        let POSCNT=$POSCNT+1
        RANDSTR="${RANDSTR}${CHARS[${RANDOM}%${CNUM}]}"
    done
    echo "${RANDSTR}"
}
need=$(genstr 1 1 2 3 4)
genstr $need 0 1

Here is an example of running it 10 times:

100
00
0001
000
10
1100
1
1010
111
10

Thanks all, beefstu that looks really good -- let me fiddle with it a bit and see if I can get it to do everything I need it to and then I'll get back to you.
Cheers,
V

'Cause I like PERL (and I am procrastinating from splitting word):

use strict;
use warnings;

$\ = "\n";
$, = '';

if (@ARGV < 3) {
    use File::Basename;
    my $NAME = basename $0;

    print STDERR "USAGE: $NAME <count> <length> <word>...";
    print STDERR '    <count> and <length> are <n> or <min>-<max>';
    exit 1;
}

my $count  = shift @ARGV;

my ($count_n, $count_w) = $count =~ m{^(\d+)(?:-(\d+))?} ;

if (defined $count_w) {
    if ($count_n < $count_w) {
        $count_w -= $count_n - 1;
    }
    else {
        print $ARGV, '(', $., '): invalid count - ', $count;
        next;
    }
}
elsif (defined $count_n) {
    $count_w = 1;
}
else {
    print $ARGV, '(', $., '): invalid count - ', $count;
    next;
}

my $length = shift @ARGV;

my ($length_n, $length_w) = $length =~ m{^(\d+)(?:-(\d+))?} ;

if (defined $length_w) {
    if ($length_n < $length_w) {
        $length_w -= $length_n - 1;
    }
    else {
        print $ARGV, '(', $., '): invalid length - ', $length;
        next;
    }
}
elsif (defined $length_n) {
    $length_w = 1;
}
else {
    print $ARGV, '(', $., '): invalid length - ', $length;
    next;
}

my $c = $count_n + int rand $count_w;

while (0 < $c--) {
    my @R = ();

    my $l = $length_n + int rand $length_w;

    while (0 < $l--) {
        push @R, $ARGV[int rand @ARGV];
    }

    print @R;
}

To use:

scriptname count length word...

where number of strings, count, and the length of each string, length, can be of the form N or min-max . Each word will be randomly picked. For example:

./scriptname 10 1-4 0 1

could generate:

01
1
01
1
101
010
10
001
1
01

and

./scriptname  1-80 10-50 0 1
0010010110110111111001101011110110
1110010101110111000101110
00001100111000100101000101100100110000110
1010111011110100001100
0110100100010
001010001101000
00001011000011100110101001110101011011010001010
01000001110101111001101011000001101001101000
100100111111110011111010101101111101111001100111
11101000010
11111110001010011101000001011111101000101110
1100000101101001010
01001111010110111101111110000101
11111101111010010100010101101000101110011011
100011100000010101110100
1000111100101000111011011101101000

and

./scriptname  1-16 8-32 C T G A
CTGCCGAAAGCGGCTGGGTT
GAATCCCGC
AGACCACAAGAAAAGCCCTGC
GACAATCAATGATGCATCTCTGTCAGCTAA
TATGAGTTGTCCCGGCCGTT