There are several modules on CPAN for generating random passwords, but last time I checked, none of them are flexible enough. Different websites or applications have different requirements (sometimes ridiculous ones) for passwords. True, most modules allow setting minimum/maximum length, and some of them allow customizing the number of special characters, or number of digits, but what I want is some sort of template/pattern that the generator would follow. So I created genpw.

Basic functionality

genpw is your usual random password generator CLI. When run without any arguments, it returns a single random password (8-20 characters long, comprising letters/digits):

% genpw J9K3ZjBVR

To return several passwords:

% genpw 5 wAYftKsS knaY7MOBbcvFFS3L1wyW oQGz62aF sG1A9reVOe Zo8GoFEq

To set exact length or minimum/maximum of length:

% genpw -l 4 1CN4

% genpw --min-len 12 --max-len 14 nqBKX5lyyx7B

Patterns

In addition to the above basic customization, genpw allows you to specify a pattern (or several patterns to pick randomly, for that matter). A pattern is a string that is similar to a printf pattern where conversion sequences like %d will be replaced with actual random characters. Here are the available conversions:

%l Random Latin letter (A-Z, a-z) %d Random digit (0-9) %h Random hexdigit (0-9a-f) %a Random letter/digit (Alphanum) (A-Z, a-z, 0-9; combination of %l and %d) %s Random ASCII symbol, e.g. "-" (dash), "_" (underscore), etc. %x Random letter/digit/ASCII symbol (combination of %a and %s) %m Base64 character (A-Z, a-z, 0-9, +, /) %b Base58 character (A-Z, a-z, 0-9 minus IOl0) %B Base56 character (A-Z, a-z, 0-9 minus IOol01) %% A literal percent sign %w Random word

You can specify %NC (where N is a positive integer, and C is the conversion) to mean a sequence of random characters (or a random word) with the exact length of N. Or %N$MC (where N and M are positive integers) to mean random characters (or word) with length between N and M.

Unsupported conversion will be unchanged, like in printf .

Some examples:

Generate random digits between 10 and 12 characters long:

% genpw -p '%10$12d' 55597085674

Generate a random UUID:

% genpw -p '%8h-%4h-%4h-%4h-%12h' ff26d142-37a8-ecdf-c7f6-8b6ae7b27695

Like the above, but in uppercase:

% genpw -p '%8h-%4h-%4h-%4h-%12h' -U 22E13D9E-1187-CD95-1D05-2B92A09E740D

Words

The %w conversion in pattern mean to replace with a random word. Words are fetched from STDIN (and will be shuffled before use). For example, the command below will generate password in the form of a random word + 4 random digits:

% genpw -p '%w%4d' < /usr/share/dict/words shafted0412

Instead of from STDIN, you can also fetch words from the various WordList::* modules available on CPAN (and installed locally). A separate CLI provides this functionality: genpw-wordlist, which is basically just a wrapper to extract the words from the wordlist module(s) then feed it to App::genpw. By default, if you don't specify -w option(s) to select wordlist modules, the CLI will use WordList::EN::Enable:

% genpw-wordlist -p '%w%4d' sedimentologists8542

Generate 5 passwords comprising 8-character word followed by between four to six random digits:

% genpw-wordlist 5 -p '%8w-%4$6d' alcazars-218050 pathogen-4818 hogmanes-212244 pollened-3206 latinity-21053

Configuration file

To avoid you from having to type patterns again and again, you can use a configuration file. For example, put this in $HOME/genpw.conf :

[profile=uuid] patterns = %8h-%4h-%4h-%4h-%12h case = upper

then you can just say:

% genpw -P uuid 7B8FB8C6-0D40-47A3-78B7-848A114E5C6D

Speed

The speed is not great, around 2000 passwords/sec on my laptop, though I believe this should not matter for most use-cases.

Closing

genpw is a flexible random password generator where you can specify patterns or templates for the password. I'm still working on a few things, like how to enable secure random source in the most painless way. There are also various CLI variants to generate specific kinds of passwords as straightforward as possible: genpw-base56, genpw-base64, genpw-id, and the aforementioned genpw-wordlist.