kaos
I recently decided to learn Erlang. As my first endeavor I created a combinator library for generating dynamic random values and data structures. The documentation is quite extensive and gives many usage examples.
The one thing missing is pre-defined character sets. This is intentional as I intend to add an additional module that offers a more robust and comprehensive system of composing character sets from Unicode code points.
With that said, it is quite easy to create your own character set generators as can be seen from the examples included in this post.
I would love to hear feedback on what features or enhancements might be useful, or any comments on the API design. I am happy to answer any questions or how-tos.
Features
Basic Types
Boolean
Bit
Byte
Bitstring
Binary
Integer
Float
String
Data Structures
Array
List
Map
Set
Tuple
(And the main data structures of the standard library such as dict, orddict, gb_set, etc.)
Operations
All
Choose
Const
Cycle
Iterate
Recurse
Weighted
Modifiers
Filter
Flatmap
Map
Shuffle
Examples
Random Password Generator
Password will contain 2 special characters, 1 uppercase letter, 1 lowercase letter, 1 number, and the remainder containing those or other symbols. Then the chosen characters are shuffled.
1> GenSpecialW = {_, GenSpecialC} = kaos:weighted_from_list([$!, $@, $#, $$, $%, $^, $&, $*, $(, $), $_, $+, $-, $=]).
2> GenUpperW = {_, GenUpperC} = kaos:weighted_from_range($A, $Z).
3> GenLowerW = {_, GenLowerC} = kaos:weighted_from_range($a, $z).
4> GenNumberW = {_, GenNumberC} = kaos:weighted_from_range($0, $9).
5> GenSymbolW = kaos:weighted_from_list([$(, $), $_, $+, $-, $=, ${, $}, $[, $], $:, $;, $<, $>, $,, $., $?, $/]).
6> GenFiller = kaos:weighted([GenSpecialW, GenUpperW, GenLowerW, GenNumberW, GenSymbolW]).
7> GenAll = kaos:all([
7> kaos:list_of(kaos:const(2), GenSpecialC),
7> kaos:list_of(kaos:const(1), GenUpperC),
7> kaos:list_of(kaos:const(1), GenLowerC),
7> kaos:list_of(kaos:const(1), GenNumberC),
7> kaos:list_of(kaos:const(12 - 5), GenFiller)
7> ]).
8> GenPass = kaos:flatmap(fun (Gs) -> kaos:shuffle(lists:flatten(Gs)) end, GenAll).
9> {ok, [Pass]} = kaos:generate(GenPass, 909, 1).
10> Pass.
"6+LP!J}vaj1sg(+K:("
Random JSON Document Generator
1> GenNestSize = kaos:integer(1, 4).
2> GenFloat = kaos:float(-12.0, 12.0).
3> GenInteger = kaos:integer(-12, 12).
4> GenString = kaos:string_of(kaos:integer(1, 12), kaos:integer($a, $z)).
5> GenPrimitive = kaos:choose([kaos:boolean(), GenFloat, GenInteger, GenString]).
6> GenJson =
6> kaos:recurse(fun (Depth) ->
6> case Depth < 3 of
6> true -> kaos:weighted([
6> {3, GenPrimitive},
6> {2, kaos:choose([
6> kaos:list_of(GenNestSize, kaos:recurse(fun(_) -> GenPrimitive end)),
6> kaos:map_of(GenNestSize, GenString, kaos:recurse(fun(_) -> GenPrimitive end))
6> ])}
6> ]);
6> false -> GenPrimitive
6> end
6> end).
7> {ok, [Json]} = kaos:generate(GenJson, 909, 1).
8> io:format("~ts~n", [json:format(Json)]).
[
{
"aavquho": { "sitygndpvol": 2 },
"butquytalbd": [
[-8,{
"mq": false,
"zkcrikbkpb": 5.512894632507528
}],
"oeggzc",
true
],
"q": 6.649188725917739,
"qb": [
[false,false,"suzsscusndhq"],
"ysvoe",
"yjidecscisc"
]
},
false,
false
]
ok