Commit | Line | Data |
---|---|---|
9c8765b4 | 1 | #!/bin/bash |
c21c5eee SBS |
2 | # Desc: Generate passphrase with specified number of bits of entropy |
3 | # Usage: bknpass [integer] | |
4 | # Example: bknpass 256 | |
5 | # Result: 9tnzcl0m4dsm22a95525zj93jj | |
6 | # Version: 0.2.0 | |
7 | # Depends: bash 5.1.8, GNU coreutils 8.32, bc 1.07.1, awk 5.1.0 | |
8 | # License: | |
9c8765b4 | 9 | # `bknpass`, an alphanumeric password generator |
c21c5eee | 10 | # Copyright (C) 2022 Steven Baltakatei Sandoval (baltakatei.com) |
9c8765b4 SBS |
11 | # |
12 | # This program is free software: you can redistribute it and/or modify | |
13 | # it under the terms of the GNU General Public License as published by | |
14 | # the Free Software Foundation, either version 3 of the License, or | |
15 | # any later version. | |
16 | # | |
17 | # This program is distributed in the hope that it will be useful, | |
18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | # GNU General Public License for more details. | |
21 | # | |
22 | # A copy of the GNU General Public License may be found at | |
23 | # <https://www.gnu.org/licenses/>. | |
9c8765b4 | 24 | |
c21c5eee SBS |
25 | yell() { echo "$0: $*" >&2; } # print script path and all args to stderr |
26 | die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status | |
27 | try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails | |
28 | showUsage() { | |
29 | # Desc: Display script usage information | |
30 | # Usage: showUsage | |
31 | # Version 0.0.1 | |
32 | # Input: none | |
33 | # Output: stdout | |
34 | # Depends: GNU-coreutils 8.30 (cat) | |
35 | cat <<'EOF' | |
36 | USAGE: | |
37 | bknpass [int entropy_bit_count] | |
9c8765b4 | 38 | |
c21c5eee SBS |
39 | EXAMPLE: |
40 | bknpass 128 | |
41 | EOF | |
42 | }; # Display information on how to use this script. | |
43 | main() { | |
44 | # Desc: main program | |
45 | # Usage: main "$@" | |
46 | # Input: $1: integer bits of entropy | |
47 | # Output: stdout: string passphrase | |
48 | # Depends: bash 5.1.8, GNU coreutils 8.32, bc 1.07.1, awk 5.1.0 | |
49 | # Ref/Attrib: [1] "Check existence of input argument in a Bash shell script". https://stackoverflow.com/a/6482403 | |
50 | # [2] "How do I test if a variable is a number in Bash?". https://stackoverflow.com/a/806923 | |
51 | # [3] "Round a Number in a Bash Script". https://bits.mdminhazulhaque.io/linux/round-number-in-bash-script.html | |
52 | # [4] "Logarithms in GNU bc". https://web.archive.org/web/20210211050732/http://phodd.net/gnu-bc/bcfaq.html#bclog | |
53 | # [5] "BIP 173". Note: bech32 charset. https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki | |
54 | # [6] "Bash Function to generate random password". https://www.thegeekstuff.com/2010/04/unix-bash-function-examples/ | |
55 | charset="qpzry9x8gf2tvdw0s3jn54khce6mua7l"; # bech32. See [2]. | |
56 | alphabet_size="$(echo -n "$charset" | wc -c)"; # number of unique chars | |
57 | log_base=2; # entropy unit base (i.e. 2 for "bits of entropy") | |
9c8765b4 | 58 | |
c21c5eee SBS |
59 | # Check for bc |
60 | if ! command -v bc 1>/dev/null 2>&1; then die "ERROR:bc not available"; fi; | |
9c8765b4 | 61 | |
c21c5eee SBS |
62 | ## Get entropy_bit_count |
63 | if [[ -z "$1" ]]; then | |
64 | ### prompt user | |
65 | showUsage; | |
66 | echo -n "Please specify the required strength of the password in bits of entropy (ex: 256):" 1>&2; # prompt via stderr | |
67 | read -r entropy_bit_count | |
68 | else | |
69 | entropy_bit_count="$1"; | |
70 | fi; # See [1]. | |
9c8765b4 | 71 | |
c21c5eee SBS |
72 | ## Check entropy_bit_count |
73 | pattern="^[0-9]+$"; | |
74 | if ! [[ $entropy_bit_count =~ $pattern ]] ; then die "ERROR:Not an integer:$entropy_bit_count"; fi; # See [2] | |
9c8765b4 | 75 | |
c21c5eee SBS |
76 | ## Calculate minimum count of chars needed for passphrase as float using 'bc' |
77 | ### Solve ln(a^n)/ln(2)=b for n where: | |
78 | ### a=$alphabet_size | |
79 | ### n=$char_count_float | |
80 | ### b=$entropy_bit_count | |
81 | char_count_float="$(echo "$entropy_bit_count*l($log_base)/l($alphabet_size)" | bc -l)"; | |
9c8765b4 | 82 | |
c21c5eee SBS |
83 | ## Round $char_count_float to next highest integer |
84 | char_count="$(echo "$char_count_float" | awk '{print ($0-int($0)>0)?int($0)+1:int($0)}')"; # See [3] | |
9c8765b4 | 85 | |
c21c5eee SBS |
86 | ## Generate and output passphrase |
87 | echo "$(LC_ALL=C tr -cd "$charset" < /dev/urandom | head -c "$char_count")"; # See [6] | |
88 | }; # main program | |
9c8765b4 | 89 | |
c21c5eee | 90 | main "$@"; |
9c8765b4 SBS |
91 | |
92 | #==References== | |
93 | # | |
94 | # - How to echo a string as stderr instead of stdout. | |
95 | # https://stackoverflow.com/a/2990533 | |
96 | # Author: James Roth | |
97 | # Date: 2010-06-07T14:52Z | |
98 | # Date Accessed: 2020-01-20 | |
99 | # | |
100 | # - How to check if script argument exists or not. | |
101 | # https://stackoverflow.com/a/6482403 | |
102 | # Author: phoxix | |
103 | # Date: 2011-06-26T05:55Z | |
104 | # Date Accessed: 2020-01-20 | |
105 | # | |
106 | # - How to check that a string is an integer using regular expression test. | |
107 | # https://stackoverflow.com/a/806923 | |
108 | # Author: Charles Duffy | |
109 | # Date: 2009-04-30T13:32Z | |
110 | # Date Accessed: 2020-01-20 | |
111 | # | |
112 | # - How to use `bc` to calculate logarithms in Bash | |
113 | # http://phodd.net/gnu-bc/bcfaq.html#bashlog | |
114 | # Author: unknown | |
115 | # Date Accessed: 2020-01-20 | |
116 | # | |
117 | # - How to use `awk` to convert and round up a float to an integer. | |
118 | # https://bits.mdminhazulhaque.io/linux/round-number-in-bash-script.html | |
119 | # Author: Md. Minhazul Haque | |
120 | # Date: 2015-01-09 | |
121 | # Date Accessed: 2020-01-20 | |
122 | # | |
123 | # - How to use `/dev/urandom`, `tr`, and `head` to generate a random password in Bash. | |
124 | # https://www.thegeekstuff.com/2010/04/unix-bash-function-examples/ | |
125 | # Author: SASIKALA, Ramesh Natarajan | |
126 | # Date: 2010-04-21 | |
127 | # Date Accessed: 2020-01-20 | |
128 | # | |
8fd9a3cb SBS |
129 | # - Bech32 base32 charset |
130 | # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki | |
131 | # Author: Pieter Wuille <pieter.wuille@gmail.com> | |
132 | # Date: 2017-03-20 | |
133 | # License: BSD-2-Clause | |
134 | # Date: Accessed: 2021-01-23 | |
135 | # | |
c21c5eee | 136 | # - Dependencies: bash, bc, echo, awk, tr, head |
9c8765b4 | 137 | # |
c21c5eee SBS |
138 | # - GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-gnu) |
139 | # Copyright (C) 2020 Free Software Foundation, Inc. | |
9c8765b4 SBS |
140 | # License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> |
141 | # This is free software; you are free to change and redistribute it. | |
142 | # There is NO WARRANTY, to the extent permitted by law. | |
c21c5eee SBS |
143 | # |
144 | # - bc 1.07.1 | |
145 | # Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc. | |
146 | # | |
147 | # - echo (GNU coreutils) 8.32 | |
148 | # Copyright (C) 2020 Free Software Foundation, Inc. | |
9c8765b4 SBS |
149 | # License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. |
150 | # This is free software: you are free to change and redistribute it. | |
151 | # There is NO WARRANTY, to the extent permitted by law. | |
152 | # | |
153 | # Written by Brian Fox and Chet Ramey. | |
c21c5eee SBS |
154 | # |
155 | # - GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1) | |
156 | # Copyright (C) 1989, 1991-2020 Free Software Foundation. | |
157 | # | |
9c8765b4 SBS |
158 | # This program is free software; you can redistribute it and/or modify |
159 | # it under the terms of the GNU General Public License as published by | |
160 | # the Free Software Foundation; either version 3 of the License, or | |
161 | # (at your option) any later version. | |
c21c5eee | 162 | # |
9c8765b4 SBS |
163 | # This program is distributed in the hope that it will be useful, |
164 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
165 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
166 | # GNU General Public License for more details. | |
c21c5eee | 167 | # |
9c8765b4 SBS |
168 | # You should have received a copy of the GNU General Public License |
169 | # along with this program. If not, see http://www.gnu.org/licenses/. | |
170 | # | |
c21c5eee SBS |
171 | # - tr (GNU coreutils) 8.32 |
172 | # Copyright (C) 2020 Free Software Foundation, Inc. | |
9c8765b4 SBS |
173 | # License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. |
174 | # This is free software: you are free to change and redistribute it. | |
175 | # There is NO WARRANTY, to the extent permitted by law. | |
c21c5eee | 176 | # |
9c8765b4 | 177 | # Written by Jim Meyering. |
c21c5eee SBS |
178 | # |
179 | # - head (GNU coreutils) 8.32 | |
180 | # Copyright (C) 2020 Free Software Foundation, Inc. | |
9c8765b4 SBS |
181 | # License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. |
182 | # This is free software: you are free to change and redistribute it. | |
183 | # There is NO WARRANTY, to the extent permitted by law. | |
c21c5eee | 184 | # |
9c8765b4 | 185 | # Written by David MacKenzie and Jim Meyering. |