1
1
import argparse # to work with the arguments
2
2
import string
3
- import random
3
+ import secrets
4
4
5
5
6
6
# function to generate the password
@@ -15,26 +15,26 @@ def get_password(length: int) -> str:
15
15
password = ''
16
16
17
17
# adding one symbol
18
- password += random .choice (symbols )
18
+ password += secrets .choice (symbols )
19
19
20
20
# adding one number
21
- password += random .choice (numbers )
21
+ password += secrets .choice (numbers )
22
22
23
23
# adding one lowercase character
24
- password += random .choice (lowercase_characters )
24
+ password += secrets .choice (lowercase_characters )
25
25
26
26
# adding one uppercase character
27
- password += random .choice (uppercase_characters )
27
+ password += secrets .choice (uppercase_characters )
28
28
29
29
# now run a for loop starting from the current length of the password
30
30
# all the way to the maxium length to fill in the remaining data
31
31
while len (password ) < length :
32
32
# adding all the data together into a one list
33
- characters = list ( lowercase_characters ) + list ( uppercase_characters )
34
- data = symbols + numbers + characters
33
+ characters = lowercase_characters + uppercase_characters
34
+ data = symbols + numbers + list ( characters )
35
35
36
36
# getting a random character from the list
37
- random_char = random .choice (data )
37
+ random_char = secrets .choice (data )
38
38
39
39
# if asked to exclude duplicates
40
40
if args .excludeduplicates :
@@ -46,6 +46,77 @@ def get_password(length: int) -> str:
46
46
# then just add the character without checking
47
47
password += random_char
48
48
49
+ # create a list of the password
50
+ password_list = list (password )
51
+ # shuffle the list into random sequence
52
+ password = shuffle (password_list )
53
+
54
+ # returning the password
55
+ return password
56
+
57
+
58
+ # shuffle function based on Fisher–Yates shuffle using secrets.choice
59
+ # as the integer selector
60
+ def shuffle (password : list ):
61
+ # n used to determine range of loop
62
+ n = len (password )
63
+ # Fisher
64
+ for x in range (n - 1 , 0 , - 1 ):
65
+ # set new variable y to random int within needed index
66
+ y = secrets .choice (range (0 , x + 1 ))
67
+ # swap elements at index x and index y
68
+ password [x ], password [y ] = password [y ], password [x ]
69
+ # return concatenated password
70
+ return '' .join (password )
71
+
72
+ # main method
73
+
74
+
75
+ def main (args : argparse .Namespace ) -> None :
76
+ # storing the length in a variable
77
+ length = args .length
78
+
79
+ # if the value is out of range then inform the user and exit
80
+ # if length < 6 or length > 20:
81
+ # print('ERROR: -l/--length should be in the range of 6 - 20')
82
+ # exit(0)
83
+
84
+ # this will hold the final password
85
+ password = get_password (length )
86
+
87
+ # printing the password to the user
88
+ print (f'PASSWORD: { password } ' )
89
+
90
+
91
+ if __name__ == '__main__' :
92
+ # creating the argparse object
93
+ parser = argparse .ArgumentParser ()
94
+
95
+ # adding the length argument
96
+ parser .add_argument (
97
+ '-l' , '--length' ,
98
+ help = 'Length of the password. [MIN=6], [MAX=20], [DEFAULT = 6]' ,
99
+ metavar = '' ,
100
+ default = 6 ,
101
+ type = int
102
+ )
103
+
104
+ # adding the exclude duplicates argument
105
+ parser .add_argument (
106
+ '-ed' ,
107
+ '--excludeduplicates' ,
108
+ action = 'store_true' ,
109
+ help = 'Exculdes duplicate characters from the password'
110
+ )
111
+
112
+ # parsing the argument
113
+ args = parser .parse_args ()
114
+
115
+ # calling the main method with the args
116
+ main (args )
117
+
118
+ password += random_char
119
+
49
120
# shuffling the generated password to mix every character
50
121
# creating a list of the password
51
122
password_list = list (password )
0 commit comments