Well, since this is a thread for password generators, I'll add one I came up with just last month. (Hope you don't mind, jbsnake.) This has a few bells and whistles, along with sanity checks.
However, the actual generator I came up with is very fast and does a good job of creating random characters.....
The features include:
* Allows for generating one or more passwords at a time
* You can specify a fixed length or a length range (min-max), within limits
* When a range is specified, along with more than one password, the length of each password will also be random
* And did I say it was fast? 
Anyway, enough with the hype. It is well commented to make it easier to follow along:
Code:
#! /bin/bash
################################################################################
# genpass - a random password generator
#
# Written by CTWaley (aka, thegeekster), (c) August 2006
#
# You may do anything you want with this script, as long as the line directly
# above remains with it. Which means, give credit where credit is due!
#
################################################################################
## Self explanatory what this is for ;-)
print_usage(){
cat<<_USAGE_
Usage: ${0##*/} [-n #] length
${0##*/} [-n #] min-max
Genpass creates passwords whose length is N, with an optional number
of passqwords to generate (-n #). If an optional range is given
(min-max), the length of the password will be randomly chosen within
that range, inclusively. And if more than one password is requested,
the length will be different for each password generated.
NOTE: The range cannot be lower than 6 or greater than 15 (6-15), as
this is the acceptable limits for most websites or user logins."
_USAGE_
}
## The generator "engine" - what all the fuss is about :-D
gen_pass(){ echo $(tr -dc "$CHARS" </dev/urandom | head -c $1) ;}
## First off, we must have something to work with from the command line:
test -z "$*" && print_usage >&2 && exit 1 ## If empty, show usage and bail
## This is needed to produce alphanumeric characters independent of locale
## (ie., characters that are not part of the "extended" ascii chart) when using
## the [:alnum:] character class:
export LC_ALL=C
## Reseed the $RANDOM variable, using the PID of this script (which changes each
## time the script runs). This should produce a much more random generation of
## numbers from the $RANDOM variable with each run of the script:
RANDOM=$$
## CHARS is for the characters you want to include in your password, such as
## letters, numbers, and punctuation. IMPORTANT: If using a dash, it must be the
## last character, or 'tr' will complain:
CHARS='[:alnum:]_!()$@#&+=-'
## Do we have a request for more than one password?
if [[ "$1" =~ "^-c" ]]; then
## Chop off the option switch in $1 to see if NUM is appended to the switch
NUM="${1/-c/}"; if [ -z "$NUM" ]; then
## If NUM is empty, assign $2 to NUM and shift the command args twice
NUM="$2" && shift 2
test -z $NUM && ## Make sure NUM is not empty
{ echo -e "\n Not enough arguments on the command line.\n" && exit;}
else ## It must not be empty, so we'll only need to shift once
shift 1
fi
## Do we have a valid number to work with and not any non-digit characters:
[[ "$NUM" =~ "[^0-9]" ]] &&
{ echo -e "\n '$1' is not a valid whole number for the number of passwords to generate.\n"
print_usage >&2 && exit 1;}
## Now, after all the shifting around, do we have any args left?:
test -z "$1" && print_usage >&2 && exit 1 ## Oops, we forgot the LEN (or NUM)
else ## Here we don't have any request for more than one password, so we'll need just one
NUM=1
fi
## Well, if we made it this far, then everything must be okay (so far)
## Okay, are we dealing with a specified length or have a range to work with?
if [[ "$1" =~ "-" ]]; then ## If true, we're dealing with a random length (range)
## We'll assign the range to an array, if a range was specified in the argument.
RANGE=(${1/-/ }) ## Convert the dash to a space when assigning to an array
## Testing for min/max length requirements:
test ${RANGE[0]} -lt 6 -o ${RANGE[1]} -gt 15 &&
{ printf '%s\n' '' ' Sorry, but the acceptable length for a password is 6-15 characters.' \
' (Note - some sites will only allow passwords no greater then 12' \
' characters in length.) :-(' '' >&2
exit 1;}
## Now we will produce the actual random length(s) within the specified range:
for ((INT=1 ; INT<=NUM ; INT++)); do ## We're looping for the NUM of passwords
SEED=$RANDOM
LEN=$((((SEED %= (RANGE[1] - RANGE[0])) + 1) + RANGE[0]))
gen_pass $LEN
done
else ## If not a number range, then we only have one length to deal with:
for ((INT=1 ; INT<=NUM ; INT++)); do ## Again, loop for the NUM of passwords
gen_pass $1
done
fi
exit 0
---thegeekster
