58 lines
1.5 KiB
OCaml
58 lines
1.5 KiB
OCaml
let lower = "abcdefghijklmnopqrstuvwxyz"
|
|
let upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
let digit = "0123456789"
|
|
let other = "!\034#$%&'()*+,-./:;<=>?@[]^_{|}~"
|
|
|
|
let visually_similar = "Il1O05S2Z"
|
|
|
|
|
|
let mk_pwd len readable =
|
|
let get_char i =
|
|
match i mod 4 with
|
|
| 0 -> lower.[Random.int (String.length lower)]
|
|
| 1 -> upper.[Random.int (String.length upper)]
|
|
| 2 -> digit.[Random.int (String.length digit)]
|
|
| 3 -> other.[Random.int (String.length other)]
|
|
| _ -> raise Exit
|
|
in
|
|
let f =
|
|
if readable then
|
|
(fun i ->
|
|
let rec aux () =
|
|
let c = get_char i in
|
|
if String.contains visually_similar c
|
|
then aux ()
|
|
else (String.make 1 c)
|
|
in
|
|
aux ()
|
|
)
|
|
else
|
|
(fun i ->
|
|
let c = get_char i in
|
|
(String.make 1 c)
|
|
)
|
|
in
|
|
let r = Array.init len f in
|
|
Array.sort (fun _ _ -> (Random.int 3) - 1) r;
|
|
(String.concat "" (Array.to_list r))
|
|
|
|
|
|
let () =
|
|
Random.self_init ();
|
|
let num = ref 1 in
|
|
let len = ref 8 in
|
|
let readable = ref false in
|
|
let speclist = [
|
|
"-n", Arg.Set_int num, "number of passwords";
|
|
"-c", Arg.Set_int len, "number of characters";
|
|
"--readable", Arg.Set readable, "readable";
|
|
"--rand-init", Arg.String (fun s ->
|
|
Random.full_init
|
|
(Array.map int_of_char (Array.of_seq (String.to_seq s)))
|
|
), "initialise the random generator with a string";
|
|
] in
|
|
Arg.parse speclist (fun s -> invalid_arg s) "Password generator";
|
|
for i = 1 to !num do
|
|
print_endline (mk_pwd !len !readable)
|
|
done
|