aboutsummaryrefslogblamecommitdiffstats
path: root/README.md
blob: 6258c881137bb2283f86bf38c7b02f7cff338939 (plain) (tree)



















































































                                                                                                                  
                                                                        
                            

                                                                                  
 


                                                                               
 


                                                                                 
 






                                                                                     

       













                                                    
   











                                                                              
# makepass

*This is a work in progress!*

I wrote `makepass` long ago to just spit out some random strings I could use as
passwords.

The first versions has been lost to time, and `makepass` was first commited to a
git-repo in 2018, as part of my dotfile-repo
[idgatt](https://git.dnns.no/idgatt/) ("It's Dangerous to Go Alone, Take
This!").

`makepass` was first written as a bash-script, but it was a zsh-script when I
commited it to my dotfile-repo. It was later changed back to a bash-script, and
in 2022 I rewrote it as both a POSIX shell-script and as a zsh-script.

Around then I found some joy in tinkering with the script, and I did some
optimalization of the zsh-script to minimilize forks and runtime. It is now pure
zsh, and does not fork out to any other programs.

Recently I decided I wanted to try to recreate makepass in other languages, and
maybe see if I can make it even faster.

## makepass specifications
Here's an attempt to specify how `makepass` should work. Might be useful for future versions.

`./makepass` is a symlink that points to whichever of the scripts I think is the best at any given time.

`makepass` should, by default, output:
- 10 "normal" passwords
    - random characters from the "normal" character set (see below)
- 6 passwords with special characters
    - first and last random character: alphanumerical
    - the rest are random characters: from the "special" character set
- 6 passphrases put together from a wordlist the user can define (using
  `/usr/share/dict/words` by default), separated by hyphens

If an (one) argument is supplied on the command line, it should be a number
between (including) 0 and 255, else an error should be shown. This argument
defines the length of the random passwords. If no argument is provided, every
password (not passphrase) should be of a random length between (including) 8
and 42 character

The passwords should *preferably* be output in columns. The number of columns
should be dynamic, and dependant on the width of the screen.

### Character sets

Normal character set: `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_`

Special character set: `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&/()=?+-_,.;:<>[]{}|\@*`

### Example output

```
Normal passwords:
7B39aQZSm9P9BYZ8gBu0rLNIjNP                 SLztHlkZ5IsG5VaMfeF_JgttZOfZZa5
RxnvFtdztaX                                 jZ6lAAA2a38ip5gwr_LuIDOys2Co
kn3hGdRMyIyz1sJic5iNL6N5                    3Z9wWyScY4qqQYh
wigDZcuGDlWDyW4UKNtC_NHg9ITVfLOUq4Iq4R      dJJSK10_SDk7q6Jk
41uPXf5d-jYCh7wgc0ZOy                       hTTcPdqGg5NWCyf7vcFp3su4kGQ0aIyP7xK7WVcp

Passwords with special characters:
p0M4b1%XP.BsIDH1ub[q9b+3nSR84!W$<e          ZLz80iY]ZT%RcA*H
txX4e-vYf0ZO2hG20h[d                        Y!H0d1K4Vz*2z6U=?Yotk
hw!b;bK||[Bx                                gmrqB$nz[k!/fwV4>W%W

Passphrases:
brisk-gong-gag-open-life-boil
womb-nanny-stove-word-ajar-ocean
sage-barge-barge-five-poise-coach
lunar-juror-savor-unit-boil-sleep
cloth-nap-word-shun-gulp-sedan
guide-fray-dial-grid-candy-wick
```

## Benchmarks
I started out using just zshs `time` to time the runtime, but recently I started
checking out [hyperfine](https://github.com/sharkdp/hyperfine) which does a
nice job.

Here are the results so far:

```
% hyperfine --time-unit=millisecond --warmup=1 --shell=none ./makepass.*
Benchmark 1: ./makepass.bash
  Time (mean ± σ):     422.7 ms ±   3.1 ms    [User: 95.0 ms, System: 659.0 ms]
  Range (min … max):   417.9 ms … 428.3 ms    10 runs

Benchmark 2: ./makepass.go
  Time (mean ± σ):       6.9 ms ±   0.2 ms    [User: 1.1 ms, System: 4.7 ms]
  Range (min … max):     6.3 ms …   8.1 ms    434 runs

Benchmark 3: ./makepass.pl
  Time (mean ± σ):      36.2 ms ±   0.4 ms    [User: 17.8 ms, System: 16.2 ms]
  Range (min … max):    35.6 ms …  37.9 ms    82 runs

Benchmark 4: ./makepass.sh
  Time (mean ± σ):     1107.7 ms ±  15.3 ms    [User: 276.0 ms, System: 1790.0 ms]
  Range (min … max):   1084.9 ms … 1140.3 ms    10 runs

Benchmark 5: ./makepass.zsh
  Time (mean ± σ):      25.3 ms ±   0.7 ms    [User: 12.7 ms, System: 10.8 ms]
  Range (min … max):    23.6 ms …  27.7 ms    114 runs

Summary
  './makepass.go' ran
    3.69 ± 0.15 times faster than './makepass.zsh'
    5.28 ± 0.17 times faster than './makepass.pl'
   61.62 ± 1.86 times faster than './makepass.bash'
  161.48 ± 5.22 times faster than './makepass.sh'
```

## Versions

### Bash
This version needs a bit more work.

### Go
Build width (from root folder in repo):
```
$ go build -o ../makepass.go -C go/ -ldflags "-s -w" makepass.go
```

### Perl
Perl version. I like this version.

### Shell
Needs more work.

### Zsh
This is currently the "main" version. It uses pure zsh, with no forking out to
other programs. As of adding the go-version, it is the second fastest version.