* The character set (or "charset"; the full list of possible characters to use in a password) is predefined at invocation, but the selection of a character in that list is determined by a cryptographically-driven random function (`crypto/rand` rather than simply `math/rand`).
* The order of characters in this generated password itself is then shuffled using `crypto/rand` as well.
* This is done for every single password generated.
Invocation argument/flag defaults can be specified by the variable name in `[square brackets]`. e.g. the following in your `~/.bashrc`, for instance, on Linux:
```text
export PWGEN_XLEN=32
export PWGEN_NOSYM=1
```
will by default always generate 32-character-long passwords that do not contain symbols.
WIP:
It will also offers various hashing of the generated password(s) and a separate tool (`pwverify`) to verify a password against a hash.
-a, --disable-alpha If specified, do NOT include the Alphabetical (letter) charset. [$PWGEN_NOALPHA]
-n, --disable-num If specified, do NOT include the Numerical (number) charset. [$PWGEN_NONUM]
-s, --disable-symbols If specified, do NOT include the Simple Symbols charset. [$PWGEN_NOSYM]
-S, --enable-extended-symbols If specified, include the Extended Symbols charset (these characters may cause issues in some applications). [$PWGEN_XSYMS]
-u, --count-upper= The number of minimum uppercase characters. If not specified, this is random (if in the charset). [$PWGEN_UPPER]
-U, --count-lower= The number of minimum lowercase characters. If not specified, this is random (if in the charset). [$PWGEN_LOWER]
-N, --count-numbers= The number of minimum number characters. If not specified, this is random (if in the charset). [$PWGEN_NUMNUMS]
-y, --count-symbols= The number of minimum simple symbol characters. If not specified, this is random (if in the charset). [$PWGEN_NUMSYMS]
-Y, --count-extended= The number of minimum extended symbol characters. If not specified, this is random (if in the charset). [$PWGEN_NUMXSYMS]
-d, --disable-chars= If specified, these chars should be explicitly excluded from the charset(s). Can be specified multiple times with multiple chars per switch. [$PWGEN_NOCHARS]
-e, --explicit-chars= If specified, ignore all charset selection and only use these characters to select from. Can be specified multiple times. [$PWGEN_XCHARS]
-l, --min-length= The minimum length for passwords; use 0 for no minimum limit. Set this to the same as -L/--max-length to use a fixed length. Must be <= -L/--max-length. (default: 16) [$PWGEN_MIN]
-L, --max-length= The maximum length for passwords; use 0 for no maximum limit (this is hard-capped to 256 for performance reasons). Set this to the same as -l/--min-length for a fixed length. Must be >= -l/--min-length.
PWGen does not, and will not, generate "Correct Horse Battery Stapler" passphrases (as demonstrated in [XKCD #936](https://xkcd.com/936/)).
The author of this library believes that strong, trustworthy password managers (such as [HashiCorp's](https://www.hashicorp.com/) [Vault](https://www.vaultproject.io/)) should be used to store passwords that are completely randomly (or, more likely, pseudo-randomly to be pedantic) generated with a large character space and length rather than using a combination of real words. Using real words is still susceptible to a social engineering/OSINT attack and/or dictionary attack (albeit certainly better than just using a single word, regardless of length).
The author is not unique in this belief, either. For example:
* ["@procrastilearner" on Steemit](https://steemit.com/steemstem/@procrastilearner/correct-horse-battery-staple-is-wrong) offers mathematical/algorithmic criticism
* [Ken Munro](https://www.pentestpartners.com/security-blog/correcthorsebatterystaple-isnt-a-good-password-heres-why/) speaks a little about hashcat, which offers far more advanced cracking rules than Randall Munroe (author of XKCD) may have had in mind at the time of creating that comic.
* Even the venerable and well-respected Bruce Schneier [has spoken on this scheme](https://www.schneier.com/blog/archives/2014/03/choosing_secure_1.html) -- back in 2014.
* (and so on.)
If you decide that you still need this functionality, however, I recommend using something like [the Babble library](https://github.com/tjarratt/babble).
Sticking to these tips changes the generation time for me (on my hardware) from around **1 minute** to about **1 second** for **_1 million passwords generated_**. YMMV, of course, but you will absolutely see an exponential difference in speed by sticking to the above constraints.
Many services offer "password hints". These are useless at best and provide a vulnerability at worst.
If you are prompted for these and they are required (as they usually are), generate and use strong unique passwords for each question and store those "answers" in your password manager as well. This slightly weakens your account's access security (as you now have 3 -- or however many hint prompts are required -- that can be guessed instead of just 1) potentially, depending on how they implement the hint system, but there is absolutely no requirement that they be real answers. Doing so would lead to a more easily socially-engineered access of your account.
If the service offers it, enable it. No arguments or excuses. It is the single most effective action you can take to protect your account's access and is well worth the slightly added complication of an additional auth method.