Crypt::YAPassGen - Yet Another (pronounceable) Password Generator


 use Crypt::YAPassGen;

 my $passgen = Crypt::YAPassGen->new(
    freq        =>  '/usr/share/dict/mobydick.dat',
    length      =>  10,
    post_subs   =>  [sub { $_ = uc }, "digits"],

 my $passwd = $passgen->generate();


Crypt::YAPassGen allows you to generate pronounceable passwords using a frequency file extracted from a dictionary of words. This module was inspired by Crypt::PassGen written by Tim Jenness. I started writing this module a couple of years ago, because I wasn't able to make Crypt::PassGen work with an Italian frequency file. This module also offers a different interface and a few more options than Crypt::PassGen, that's why it exists. See "SEE ALSO" for other similar modules. Please beware that passwords generated by this module are LESS secure than truly random passwords, so use it at your own risk!



my $passgen = Crypt::YAPassGen->new(%opts)

Returns a new password generator object. You can pass an hash of options: every option will be treated as a call to the object method of the same name. Allowed options are freq, length, algorithm, ascii and post_subs. If an option is not specified the newly generated object will use the following defaults:

 freq       =>  '/path_to_american-english_default_freq_file.dat',
 length     =>  8,
 algorithm  =>  'sqrt',
 ascii      =>  0,
 post_subs  =>  [],     #NONE
my $freq = Crypt::YAPassGen->make_freq($dict_file, $freq_file, $ascii)

This class method will generate a new frequency file reading from $dict_file and writing the result in $freq_file. If $dict_file is an ARRAY reference, then we consider the elements of the array as filenames and we process all of them. The $ascii flag is optional. This is useful if your locale allows for alphabetic characters out of the 7 bit Latin ASCII alphabet (for example accented characters or with umlaut). It is higly suggested to set this variable to a true value unless your locale is US-ASCII or you're sure your dictionary doesn't contain any accented character. This apporach works fine for most european locales, but I'm not sure what would happen with different locales.


my $passwd = $passgen->generate()

Generate a password with previously defined options.

my $length = $passgen->length($integer)

Get/set the desired length for generated passwords.

my $freq_file = $passgen->freq($filename)

Get/set the frequency file to use. If set to an empty string it will clear the internal frequency table and you will have to call make_freq on the object before trying to generate any new password.

my $ascii = $passgen->ascii($flag);

Get/set the ascii flag. If it's true then we are sure our passwords will be made only of 7 bit ASCII characters as long as frequency file contains only 7 bit ASCII alphabet characters and accented variants of the same.

my $algorithm = $passgen->algorithm($code_or_string)

Get/set the algorithm to calculate the sequence of letters to be addedd to the password. The returned value will be a CODE reference. The method accept as parameters either a CODE reference or a string. If it's a string it can be one of the following: "linear", "sqrt", "log" and "flat".

The "linear" algorithm calculate the sequence of characters with a function linear to the frequency of the characters. This generate really pronounceable passwords, but may be too easy to crack.

The "sqrt" algorithm is the default as the password are still pronounceable but a bit harder to crack.

The "log" algorithm is similar to the "sqrt" but not as consistent.

The "flat" algorithm is really fast, but the generated passwords look more like really random strings than pronounceable words.

If you are interested in personalizing the algorithm used you should take a look at the code, brew your own algorithm and then pass it in as a CODE reference.

my $post_subs = $passgen->add_post_sub($code_ref)

Adds a sub to the stack of procedures that will be executed once the password has been produced. The subs are supposed to modify $_ as in a for loop. Here's an example to have all upper-case passwords:

 $passgen->add_post_sub(sub { tr/a-z/A-Z/ });

Please note that if the sub lengthen the password, then it will be later truncated at the right length, but if it shorten the password then you will be left with a mutilated one.

Instead of passing a code reference you may pass a string corresponding to one of the pre-cooked subs available in this module. They are the following:

"haxor": change some of the characters into l33t version of the same

"caps": insert a random amount of upper-case characters

"digits": insert some digits with a 1 in 4 probability

my $post_subs = $passgen->post_subs([@code_refs])

Get/set the code refs to the subs that will be called after the production of the password. See add_post_sub for specification of the subs. Returns a reference to the ARRAY of subs to be processed. Example:

 $passgen->post_subs([sub { tr/t/+/ }, "caps", "haxor"]);
my $old_subs = $passgen->reset_post_subs()

Reset the ARRAY of subs. Returns a reference to the ARRAY of subs that were there.

my $freq = $passgen->make_freq($dict_file, $freq_file)

This class method will generate a new frequency file reading from $dict_file and writing the result in $freq_file. If $dict_file is an ARRAY reference then we consider the elements of the array as filenames and we process all of them. You may omit $freq_file in which case the result won't be saved to disk, but it will still be contained by $passgen so that you may use it on the fly. If you call this method when a frequency table is already loaded in the object, the new frequency will be just added to the one already present in the object so that you can mix different dictionaries.


Save the frequency table contained in the object to $filename.


-adding more post_subs?

-bit more l10n effort?


Not really a bug in itself but this module is NOT secure! Use it at your own risk!


This module was originally inspired by Crypt::PassGen by Tim Jenness so you may notice some similarities. Modules similar to this one include Crypt::GeneratePassword, String::MkPasswd, Crypt::RandPasswd and randpass.


Copyright 2002-2004 Giulio Motta

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.