Crypt::GeneratePassword(3) generate secure random pronounceable passwords


use Crypt::GeneratePassword qw(word chars);
$word = word($minlen,$maxlen);
$word = chars($minlen,$maxlen);
*Crypt::GeneratePassword::restrict = \&my_restriction_filter;
*Crypt::GeneratePassword::random_number = \&my_random_number_generator;


Crypt::GeneratePassword generates random passwords that are (more or less) pronounceable. Unlike Crypt::RandPasswd, it doesn't use the FIPS-181 NIST standard, which is proven to be insecure. It does use a similar interface, so it should be a drop-in replacement in most cases.

If you want to use passwords from a different language than english, you can use one of the packaged alternate unit tables or generate your own. See below for details.

For details on why FIPS-181 is insecure and why the solution used in this module is reasonably secure, see ``A New Attack on Random Pronounceable Password Generators'' by Ravi Ganesan and Chris Davies, available online in may places - use your favourite search engine.

This module improves on FIPS-181 using a true random selection with the word generator as mere filter. Other improvements are better pronounceability using third order approximation instead of second order and multi-language support. Drawback of this method is that it is usually slower. Then again, computer speed has improved a little since 1977.



  $word = chars($minlen, $maxlen [, $set [, $characters, $maxcount ] ... ] );

Generates a completely random word between $minlen and $maxlen in length. If $set is given, it must be an array ref of characters to use. You can restrict occurrence of some characters by providing ($characters, $maxcount) pairs, as many as you like. $characters must be a string consisting of those characters which may appear at most $maxcount times in the word.

Note that the length is determined via relative probability, not uniformly.


  $word = word($minlen, $maxlen [, $lang [, $numbers [, $caps [, $minfreq, $avgfreq ] ] ] );
  $word = word3($minlen, $maxlen [, $lang [, $numbers [, $caps [, $minfreq, $avgfreq ] ] ] );

Generates a random pronounceable word. The length of the returned word will be between $minlen and $maxlen. If you supply a non-zero value for $numbers, up to that many numbers and special characters will occur in the password. If you specify a non-zero value for $caps, up to this many characters will be upper case. $lang is the language description to use, loaded via load_language or built-in. Built-in languages are: 'en' (english) and 'de' (german). Contributions welcome. The default language is 'en' but may be changed by calling load_language with a true value as third parameter. Pass undef as language to select the current default language. $minfreq and $minsum determine quality of the password: $minfreq and $avgfreq are the minimum frequency each quad/trigram must have and the average frequency that the quad/trigrams must have for a word to be selected. Both are values between 0.0 and 1.0, specifying the percentage of the maximum frequency. Higher values create less secure, better pronounceable passwords and are slower. Useful $minfreq values are usually between 0.001 and 0.0001, useful $avgfreq values are around 0.05 for trigrams (word3) and 0.001 for quadgrams (word).


  $ratio = analyze($count,@word_params);
  $ratio = analyze3($count,@word_params);

Returns a statistical(!) security ratio to measure password quality. $ratio is the ratio of passwords chosen among all possible ones, e.g. a ratio of 0.0149 means 1.49% of the theoretical password space was actually considered a pronounceable password. Since this analysis is only statistical, it proves absolutely nothing if you are deeply concerned about security - but in that case you should use chars(), not word() anyways. In reality, it says a lot about your chosen parameters if you use large values for $count.


  $language_description = generate_language($wordlist);

Generates a language description which can be saved in a file and/or loaded with load_language. $wordlist can be a string containing whitespace separated words, an array ref containing one word per element or a file handle or name to read words from, one word per line7. Alternatively, you may pass an array directly, not as reference. A language description is about 1MB in size.

If you generate a general-purpose language description for a language not yet built-in, feel free to contribute it for inclusion into this package.


  load_language($language_description, $name [, $default]);

Loads a language description which is then available in words(). $language_description is a string returned by generate_language, $name is a name of your choice which is used to select this language as the fifth parameter of words(). You should use the well-known ISO two letter language codes if possible, for best interoperability.

If you specify $default with a true value, this language will be made global default language. If you give undef as $language_description, only the default language will be changed.


  $number = random_number($limit);

Returns a random integer between 0 (inclusive) and $limit (exclusive). Change this to a function of your choice by doing something like this:

    sub my_rng ($) {
      # suppress warning about function being redefined
      no warnings 'redefine';
      *Crypt::GeneratePassword::random_number = \&my_rng;

The default implementation uses perl's rand(), which might not be appropriate for some sites.


  $forbidden = restrict($word,$language);

Filters undesirable words. Returns false if the $word is allowed in language $lang, false otherwise. Change this to a function of your choice by doing something like this:

    sub my_filter ($$) {
      no warnings 'redefine';
      *Crypt::GeneratePassword::restrict = \&my_filter;

The default implementation scans for a few letter sequences that english or german people might find offending, mostly because of their sexual nature. You might want to hook up a regular password checker here, or a wordlist comparison.


Copyright 2002 by Jo.rg Walter <[email protected]>, inspired by ideas from Tom Van Vleck and Morris Gasser/FIPS-181.

Now maintained by Neil Bowers <[email protected]>


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