-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_password
executable file
·159 lines (116 loc) · 3.63 KB
/
generate_password
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Simple password generator
Generates a random password. Length is passed as an argument, default is 8.
Password length and complexity (weather it contains non-alphanumeric chars) can
also be configured using $GENERATE_PASSWORD_INCLUDE_SPECIAL and
$GENERATE_PASSWORD_LENGTH.
"""
import random
import sys
import os
from io import IOBase # Only used for type hints
def usage(destination: IOBase = sys.stdout) -> None:
"""Show a usage help message."""
print("""generate_password
Small secure password generator
Usage:
generate_password [<length>]
You can pass the desired password length as an argument.
Fine-Tuning password generation:
By setting environment variables, you can now fine-tune the
generation behaviour (default values also shown below):
GENERATE_PASSWORD_INCLUDE_SPECIAL=1
Set to 0 to exclude special characters.
GENERATE_PASSWORD_LENGTH=16
Password length. If a password length was given as an argument,
this value is ignored.
""", file=destination)
def get_random_password(length: int, include_special: bool = True) -> str:
"""Generate a new random password
Uses random.choice to construct the password char by char.
Args:
length (int): Number of random characters to select.
include_special (bool): Choose from a wider range of characters
Returns:
str: A total of length characters randomly generated.
"""
allowed_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
allowed_chars += 'abcdefghijklmnopqrstuvwxyz'
allowed_chars += '0123456789'
if include_special:
allowed_chars += '.,-_!?()/='
word = ''
for i in range(length):
word += random.choice(allowed_chars)
return word
def getenv_int(var_name: str, fallback_value: int) -> int:
"""
Try to get the value of an environment variable, and
convert it to an int().
If the variable is not defined, or can not be converted to
an integer, return the fallback value.
"""
try:
my_var = int(os.getenv(var_name, fallback_value))
except ValueError:
my_var = fallback_value
return my_var
def getenv_bool(var_name: str, fallback_value: bool) -> bool:
"""
Get a boolean environment variable and uses the fallback_value
on errors.
NOTE: uses Python's bool(), so everything except 0 (or None)
is treated as True.
"""
return bool(
getenv_int(
var_name,
int(
fallback_value
)
)
)
def stringIsSignedInt(value: str) -> bool:
return False in [char not in "0123456789" for char in value]
def main():
passwd_cfg = {
"length": getenv_int("GENERATE_PASSWORD_LENGTH", 16),
"includeSpecial": getenv_bool("GENERATE_PASSWORD_INCLUDE_SPECIAL", True)
}
if len(sys.argv) > 1:
if "--help" in sys.argv or "-h" in sys.argv:
# Show help and exit
usage()
sys.exit(0)
elif len(sys.argv) > 1 and "/?" in sys.argv:
"""
EASTER EGG
If "/?" is given as argument (parameter in ancient Windows style to show usage
help; Microsoft uses Unix-like parameters almost everywhere for years now.
GIVEN AN OLD SCHOOL STYLE PARAMETER?
- TIME TO APPLY SOME STRICT LIMITS TO PASSWORD LENGTH AND CONTENT!
"""
passwd_cfg["length"] = 6
passwd_cfg["includeSpecial"] = False
elif len(sys.argv) == 2 and stringIsSignedInt(sys.argv[1]):
"""
Password length given as argument
Overrides value of os.environ["GENERATE_PASSWORD_LENGTH"] !
"""
passwd_cfg["length"] = int(sys.argv[1])
else:
# Unknown argument
usage(sys.stderr)
sys.exit(1)
# No trailing newline if stdout is piped/redirected
line_end = "\n" if sys.stdout.isatty() else ""
print(
get_random_password(
passwd_cfg["length"],
passwd_cfg["includeSpecial"]
),
end=line_end
)
if __name__ == "__main__":
main()