%% @doc A password generator. %% @author Robert Lasu %% @version 0.1.0 %% @copyright 2022 Robert Lasu -module(erlPass). -export([generate/5]). gen_number(B) -> integer_to_list(B rem 9). gen_upper(B) -> [65 + (B rem 26)]. gen_lower(B) -> [97 + (B rem 26)]. gen_symbol({B, A}) -> case B rem 4 of 0 -> [32 + A rem 16]; 1 -> [58 + A rem 7]; 2 -> [91 + A rem 6]; 3 -> [123 + A rem 4] end. seed() -> <> = crypto:strong_rand_bytes(6), {A,B}. %% @doc Generates a password. %% @end -spec generate(Length, Upper, Lower, Number, Symbol) -> Pass when Length ::integer(), Upper ::boolean(), Lower ::boolean(), Number ::boolean(), Symbol ::boolean(), Pass ::list(). generate(Length,_,_,_,_) when Length < 1 -> {error, invalid_length}; generate(Length, Upper, Lower, Number, Symbol) -> generate(Length, Upper, Lower, Number, Symbol, []). %% @doc Generate a password %% see {@link generate/5} %% @end -spec generate(Length, Upper, Lower, Number, Symbol, Pass) -> RetPass when Length ::integer(), Upper ::boolean(), Lower ::boolean(), Number ::boolean(), Symbol ::boolean(), Pass ::list(), RetPass ::list(). generate(_,false,false,false,false,_) -> {error, no_char}; generate(0,_,_,_,_, Pass) -> lists:flatten(Pass); generate(Length, Upper, Lower, Number, Symbol, Pass) -> {A, B} = seed(), case A rem 4 of 0 -> generate(Number, Length, Upper, Lower, Number, Symbol, fun gen_number/1, B, Pass); 1 -> generate(Upper, Length, Upper, Lower, Number, Symbol, fun gen_upper/1, B, Pass); 2 -> generate(Lower, Length, Upper, Lower, Number, Symbol, fun gen_lower/1, B, Pass); 3 -> generate(Symbol, Length, Upper, Lower, Number, Symbol, fun gen_symbol/1, {B,A}, Pass) end. -spec generate(ToGen, Length, Upper, Lower, Number, Symbol, Fun, Args, Pass) -> RetPass when ToGen :: boolean(), Length :: integer(), Upper :: boolean(), Lower :: boolean(), Number :: boolean(), Symbol :: boolean(), Fun :: function(), Args :: term(), Pass :: list(), RetPass :: list(). generate(_, 0, _,_,_,_,_,_, Pass) -> Pass; generate(true, Length, U, L, N, S, Fun, B, Pass) -> generate(Length-1, U, L, N, S, [ Fun(B) | Pass]); generate(false, Length, U, L, N, S, _, _, Pass) -> generate(Length, U, L, N, S, Pass).