# Nushell Password Generator "nupass"
This nushell command randomly retrieves a specified number of words from a dictionary file (English with Japanese words added by @rickcogley) less than or equal to a given parameter's length, formats the words randomly with capitalization, then separates the words with some random symbols and numbers to return a password.
To use:
1. Get the dictionary file to your system using nushell's `http`:
```
http get https://raw.githubusercontent.com/RickCogley/jpassgen/master/genpass-dict-jp.txt | save genpass-dict-jp
```
...which has also been included in this folder for convenience.
2. Confirm your `$env.NU_LIB_DIRS` location, and copy the below script `2. nupass.nu` there as `nupass.nu`.
3. Set the script as executable like `chmod +x nupass.nu`
4. Specify the dictionary file's location in the script:
```
let dictfile = $"/path/to/my/genpass-dict-jp"
```
5. In the main function's flags section, confirm and edit the default symbols list, diceware delimiter and threads for par-each (double the number of your CPU cores seems to be a good sweet spot):
```
--symbols (-s): string = "!@#$%^&()_-+[]{}" # Symbols to use in password
--delimiter (-m): string = "-" # Delimiter for diceware
--threads (-t): int = 16 # Number of threads to use in par-each
```
6. Load the script with `use` in your `config.nu`, something like:
```
use nupass.nu
```
(you can specify the path as `use /path/to/nupass.nu` if you're not taking advantage of `$env.NU_LIB_DIRS`)
Reload nu, then run it to test:
```
nupass -h
nupass 5
nupass 6 --debug
nupass 8 -v diceware
nupass 8 -v diceware -m _
nupass 4 -v mixnmatch
nupass 6 -v alphanum
nupass 5 -l 8
```
### Testing
If you're making changes to the script while testing, you can just re-source the script by doing:
`use nupass.nu`
... which will reload the latest you have saved.
From `nu` version 0.79.1, you can use the standard library, and use its bench command to do a benchmark. Load the standard library by adding `use std` in your `env.nu`, reload, then assuming `nupass.nu` is in your path, you can benchmark like so:
```
std bench --rounds 10 --verbose {nupass 10}
std bench --rounds 10 --verbose {nupass 100 -v diceware}
std bench --rounds 10 --verbose {nupass 1000 -v mixnmatch}
```
If you change the `par-each` to `each` in the main list builders for instance, you'll see a significant performance hit. When I benchmarked `nupass 100`, using just `each` took 7 sec per round, whereas changing to `par-each` dropped that to about 1 sec per round.
You can tweak it a little further by setting the threads for par-each.
```
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 8}
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 16}
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 32}
```
### Caveats
I've been scripting for quite a long time, but not in nu. Input appreciated to make this more nu-esque! The script is in a decent place as of the 20230501 version.
Obviously you can just use the `random chars` or `random integers` commands but I like to have words I can read in my passwords, and I think those generated by this script have sufficient entropy.
This command doesn't let you specify a precise length.
### Acknowledgements
Thanks everyone on Discord for putting up with and answering my nubie questions @amtoine, @fdncred, @jelle, @sygmei, @kubouch and for the feedback after try number 1.