git.fiddlerwoaroof.com
Browse code

feat(password-gen): add excluded list, make algorithm work with sequences

Ed Langley authored on 01/09/2020 21:17:29
Showing 1 changed files
... ...
@@ -4,16 +4,11 @@
4 4
   (:export ))
5 5
 (in-package :fwoar.password-gen)
6 6
 
7
-(defparameter *lowercase*
8
-  '(#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p
9
-    #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))
7
+(defparameter *lowercase* "abcdefghijklmnopqrstuvwxyz")
10 8
 
11
-(defparameter *uppercase*
12
-  '(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P
13
-    #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))
9
+(defparameter *uppercase* "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
14 10
 
15
-(defparameter *numbers*
16
-  '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
11
+(defparameter *numbers* "1234567890")
17 12
 
18 13
 (defparameter *special-characters*
19 14
   '(#\! #\\ #\# #\% #\& #\* #\+ #\, #\- #\. #\: #\< #\= #\>
... ...
@@ -22,36 +17,62 @@
22 17
 (defparameter *similar-characters*
23 18
   '(#\I #\l #\1 #\| #\O #\0 #\5 #\S #\2 #\Z))
24 19
 
25
-(defun make-readable (s)
26
-  (remove-if (lambda (x) (member x *similar-characters*)) s))
20
+(defparameter *excluded-characters*
21
+  '(#\@ #\! #\[ #\] #\{ #\} #\/ #\\ #\' #\" #\& #\< #\> #\`))
27 22
 
28
-(defun shuffle-list (input-list)
29
-  (loop with l = (length input-list)
23
+(defun make-readable (flag s)
24
+  (if flag
25
+      (remove-if (lambda (x)
26
+                   (member x *similar-characters*))
27
+                 s)
28
+      s))
29
+
30
+(defun shuffle-seq (input-seq)
31
+  (loop with l = (length input-seq)
30 32
         for i below l
31
-        do (rotatef (nth i input-list)
32
-                    (nth (random l) input-list)))
33
-  input-list)
34
-
35
-(defun generate-password (len human-readable)
36
-  (let*
37
-      ((upper (if human-readable (make-readable *uppercase*) *uppercase*))
38
-       (lower (if human-readable (make-readable *lowercase*) *lowercase*))
39
-       (number (if human-readable (make-readable *numbers*) *numbers*))
40
-       (special (if human-readable (make-readable *special-characters*) *special-characters*))
41
-       (character-groups (list upper lower number special))
42
-       (initial-password (reduce (lambda (acc x)
43
-                                   (cons (nth (random (length x)) x) acc))
44
-                                 character-groups :initial-value NIL)))
45
-    
46
-    (coerce (shuffle-list (reduce (lambda (acc x)
47
-                                    (declare (ignore x))
48
-                                    (let ((group (nth (random (length character-groups)) character-groups)))
49
-                                      (cons (nth (random (length group)) group) acc)))
50
-                                  (make-list (- len 4)) :initial-value initial-password)) 'string)))
51
-
52
-(defun main (len count &optional human-readable)
33
+        do (rotatef (elt input-seq i)
34
+                    (elt input-seq
35
+                         (random l))))
36
+  input-seq)
37
+
38
+(defun sample (seq)
39
+  (elt seq
40
+       (random (length seq))))
41
+
42
+(defun generate-password (len human-readable exclude-excluded)
43
+  (let* ((upper (make-readable human-readable *uppercase*))
44
+         (lower (make-readable human-readable *lowercase*))
45
+         (number (make-readable human-readable *numbers*))
46
+         (special-initial (make-readable human-readable *special-characters*))
47
+         (special (if exclude-excluded
48
+                      (set-difference special-initial *excluded-characters*)
49
+                      special-initial))
50
+         (character-groups (list upper lower number special))
51
+         (initial-password (reduce (lambda (acc x)
52
+                                     (cons (sample x) acc))
53
+                                   character-groups
54
+                                   :initial-value NIL)))
55
+
56
+    (coerce (shuffle-seq
57
+             (reduce (lambda (acc x)
58
+                       (declare (ignore x))
59
+                       (let ((group (nth (random (length character-groups))
60
+                                         character-groups)))
61
+                         (cons (sample group)
62
+                               acc)))
63
+                     (make-list (- len 4))
64
+                     :initial-value initial-password))
65
+            'string)))
66
+
67
+(defun main (len count &optional human-readable exclude-excluded)
53 68
   (if (< len 4)
54 69
       (print "Length must be at least 4~%")
55 70
       (loop for x from 1 to count do
56
-        (princ (generate-password len human-readable))
71
+        (princ (generate-password len human-readable exclude-excluded))
57 72
         (terpri))))
73
+
74
+(defun parse-bool (str)
75
+  (case (elt (string-downcase str) 0)
76
+    ((#\t #\y) t)
77
+    ((#\f #\n) nil)))
78
+