

The logic here was kind of hard to understand, but I think this is an equivalent refactoring with comments inlined: open System | a when predicate a "-s" "-special" special all -> all special | a when predicate a "-n" "-numerics" numbers all -> all numbers | a when predicate a "-u" "-upper" upper all -> all upper | a when predicate a "-l" "-lower" lower all -> all lower (arg = short || arg = long) & not (all |> ntains (chs.)) Let predicate arg short long (chs: char) all = The usable characters are determined from the arguments custom size and if the default settings should be used is determined From the first argument or a possible empty argument list the Let inline left right = Array.append left right
PWGEN TAILS CODE
in order to make the code more readable

The - operator for lists is temporarily redefined to work with arrays | head::tail -> buildString tail chars buildString tail chars (builder.Append chars.)īelow is my version with some inline explanation: let passwordGenerator (argv: string ) = is an O(index) operation where the same operation is O(1) for arrays, further List.length is a O(n) operation - adding more inefficiency to the equation. In F#, lists are very convenient because of its operators that makes the code more readable, but in this particular algorithm, I think I would stick to use arrays for everything, because you address the list entries by index, which is not efficient for lists, because chars. You could consider to print help/information, if the argv has a "-?" entry. Maybe consider to reduce the argument list to a distinct set - unless you want the behavior. List.fold may be a solutions in this case.Īnother issue with the function is that if the argument list contains more of the same argument (for instance "-l", "-l") it will be included more than once making the result somewhat biased. Let special = rec listBuilder chars args =īesides that, I think I would think of another design, if I find my self repeating the almost same code like in this function. Instead of having buildChars as a rec function you could have an inner recursive function to the matching and then define the char lists out side of that: let buildChars chars (args: string list) : char list = If you need a contains function, the List-module has a predefined such ready to use.Įspecially buildChars seems overly messy and complicated, and it is not very efficient that the char lists ( numbers, lower, etc) are redefined for each recursion. But it fails here: let bytes : byte array = Array.zeroCreate false
PWGEN TAILS PASSWORD
In buildChars, I would expect it to produce a 16 chars password from the default settings. If calling it with an empty argument list - from this: match args with Let pass = buildString byteList characters sbĪs a first attempt in F# you have passed the test, but the overall impression is a little messy, while the algorithm seems to (almost) work as expected. Let characters = (buildChars (argv |> Array.toList)).Tail | head::tail -> buildString tail chars Array.toList Let rec buildString (bytes: byte list) (chars: char list) (builder: StringBuilder) : string = | _::tail when chars.Length = 1 -> buildChars chars tail | _::tail when chars.Length = 1 & tail.Length = 0 -> lower upper numbers | head::tail when head = "-n" || head = "-numeric" -> if tail.Length > 0 then buildChars (chars numbers) tail else chars numbers | head::tail when head = "-s" || head = "-special" -> if tail.Length > 0 then buildChars (chars special) tail else chars special | head::tail when head = "-u" || head = "-upper" -> if tail.Length > 0 then buildChars (chars upper) tail else chars upper | head::tail when head = "-l" || head = "-lower" ->if tail.Length > 0 then buildChars (chars lower) tail else chars lower | head::_ when args.Length = 1 & strContainsOnlyNumber head -> (chars lower upper numbers) Let rec buildChars chars (args: string list) : char list = Let strContainsOnlyNumber (s:string) = s |> fst | head::tail -> (head = item) || contains item tail
PWGEN TAILS GENERATOR
I do know that crypto generators are slower than pseudo rng but I figure that a crytpo generator is better for generating something that should be secure. Some things I feel like I could have done better are the command flag parsing and the actual crypto random generation itself. This is my first major project in F#, looking for any critique on how I can make it more standard or more concise.
