NAME
    Crypt::RandPasswd - random password generator based on FIPS-181

SYNOPSIS
      use Crypt::RandPasswd;
      ( $word, $hyphenated ) = Crypt::RandPasswd->word( $minlen, $maxlen );
      $word = Crypt::RandPasswd->word( $minlen, $maxlen );
      $word = Crypt::RandPasswd->letters( $minlen, $maxlen );
      $word = Crypt::RandPasswd->chars( $minlen, $maxlen );

      # override the defaults for these functions:
      *Crypt::RandPasswd::rng = \&my_random_number_generator;
      *Crypt::RandPasswd::restrict = \&my_restriction_filter;

  Run as Script
      perl Crypt/RandPasswd.pm -help

SEE ALSO
    FIPS 181 - (APG), Automated Password Generator:
    http://www.itl.nist.gov/fipspubs/fip181.htm

DESCRIPTION
    This code is a Perl language implementation of the Automated Password
    Generator standard, like the program described in "A Random Word
    Generator For Pronounceable Passwords" (not available on-line). This
    code is a re-engineering of the program contained in Appendix A of FIPS
    Publication 181, "Standard for Automated Password Generator". In
    accordance with the standard, the results obtained from this program are
    logically equivalent to those produced by the standard.

CAVEATS
  Bugs
    The function to generate a password can sometimes take an extremely long
    time.

  Deviations From Standard
    This implementation deviates in one critical way from the standard upon
    which it is based: the random number generator in this implementation
    does not use DES. Instead, it uses perl's built-in "rand()" function,
    which in turn is (usually) built on the pseudo-random number generator
    functions of the underlying C library.

    However, the random function can be replaced by the user if desired.
    (See "rng".)

Functions
  word
      word = word( minlen, maxlen );
      ( word, hyphenated_form ) = word( minlen, maxlen );

    Generates a random word, as well as its hyphenated form. The length of
    the returned word will be between minlen and maxlen.

  letters
      word = letters( minlen, maxlen );

    Generates a string of random letters. The length of the returned word is
    between minlen and maxlen. Calls "random_chars_in_range( 'a' =" 'z' )>.

  chars
      word = chars( minlen, maxlen );

    Generates a string of random printable characters. The length of the
    returned word is between minlen and maxlen. Calls
    "random_chars_in_range( '!' =" '~' )>.

  random_chars_in_range
      word = random_chars_in_range( minlen, maxlen, lo_char => hi_char );

    Generates a string of printable characters. The length of the returned
    string is between minlen and maxlen. Each character is selected from the
    range of ASCII characters delimited by (lo_char,hi_char).

  rand_int_in_range
      n = rand_int_in_range( min, max );

    Returns an integer between min and max, inclusive. Calls "rng" like so:

      n = min + int( rng( max - min + 1 ) )

  random_element
      e = random_element( \@elts )

    Selects a random element from an array, which is passed by ref.

  rng
      r = rng( n );

    "rng" is designed to have the same interface as the built-in "rand"
    function. The default implementation here is a simple wrapper around
    "rand", which is typically a wrapper for some pseudo-random number
    function in the underlying C library.

    The reason for having this simple wrapper is so the user can easily
    substitute a different random number generator if desired. Since many
    rng's have the same interface as "rand", replacing "rng()" is as simple
    as

        {
            local $^W; # squelch sub redef warning.
            *Crypt::RandPasswd::rng = \&my_rng;
        }

    See rand.

  restrict
      word = restrict( word );

    A filter. Returns the arg unchanged if it is allowable; returns undef if
    not.

    The default version of "restrict()" allows everything. You may install a
    different form to implement other restrictions, by doing something like
    this:

        {
          local $^W; # squelch sub redef warning.
          *Crypt::RandPasswd::restrict = \&my_filter;
        }

  init
    This initializes the environment, which by default simply seeds the
    random number generator.

  _random_word
    This is the routine that returns a random word. It collects random
    syllables until a predetermined word length is found. If a retry
    threshold is reached, another word is tried.

    returns ( word, hyphenated_word ).

  _random_unit
    Selects a gram (aka "unit"). This is the standard random unit generating
    routine for get_syllable().

    This routine attempts to return grams (units) with a distribution
    approaching that of the distribution of the units in English.

    The distribution of the units may be altered in this procedure without
    affecting the digram table or any other programs using the random_word
    subroutine, as long as the set of grams (units) is kept consistent
    throughout this library.

    *NOTE that where this func used to return a numeric index into the
    'rules' C-array, it now returns a gram.*

  _improper_word
    Check that the word does not contain illegal combinations that may span
    syllables. Specifically, these are:

      1. An illegal pair of units between syllables.
      2. Three consecutive vowel units.
      3. Three consecutive consonant units.

    The checks are made against units (1 or 2 letters), not against the
    individual letters, so three consecutive units can have the length of 6
    at most.

    returns boolean

  _have_initial_y
    Treating y as a vowel is sometimes a problem. Some words get formed that
    look irregular. One special group is when y starts a word and is the
    only vowel in the first syllable. The word ycl is one example. We
    discard words like these.

    return boolean

  _have_final_split
    Besides the problem with the letter y, there is one with a silent e at
    the end of words, like face or nice. We allow this silent e, but we do
    not allow it as the only vowel at the end of the word or syllables like
    ble will be generated.

    returns boolean

  get_syllable
    Generate next unit to password, making sure that it follows these rules:

    1. Each syllable must contain exactly 1 or 2 consecutive vowels, where y
    is considered a vowel.

    2. Syllable end is determined as follows:

       a. Vowel is generated and previous unit is a consonant and syllable already has a vowel. 
          In this case, new syllable is started and already contains a vowel.
       b. A pair determined to be a "break" pair is encountered. 
          In this case new syllable is started with second unit of this pair.
       c. End of password is encountered.
       d. "begin" pair is encountered legally.  New syllable is started with this pair.
       e. "end" pair is legally encountered.  New syllable has nothing yet.

    3. Try generating another unit if:

       a. third consecutive vowel and not y.
       b. "break" pair generated but no vowel yet in current or previous 2 units are "not_end".
       c. "begin" pair generated but no vowel in syllable preceding begin pair,
          or both previous 2 pairs are designated "not_end".
       d. "end" pair generated but no vowel in current syllable or in "end" pair.
       e. "not_begin" pair generated but new syllable must begin (because previous syllable ended as defined in 2 above).
       f. vowel is generated and 2a is satisfied, but no syllable break is possible in previous 3 pairs.
       g. Second and third units of syllable must begin, and first unit is "alternate_vowel".

  alt_get_syllable
    Takes an integer, the maximum number of chars to generate. (or is it
    minimum?)

    returns a list of ( string, units-in-syllable )

    *This is an alternative version of "get_syllable()", which can be useful
    for unit testing the other functions.*

  _illegal_placement
    goes through an individual syllable and checks for illegal combinations
    of letters that go beyond looking at digrams.

    We look at things like 3 consecutive vowels or consonants, or syllables
    with consonants between vowels (unless one of them is the final silent
    e).

    returns boolean.

AUTHOR
    JDPORTER@cpan.org (John Porter)

COPYRIGHT
    This perl module is free software; it may be redistributed and/or
    modified under the same terms as Perl itself.

