TLA Line data Source code
1 : // Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
2 : //
3 : // This file is part of Flipdare's proprietary software and contains
4 : // confidential and copyrighted material. Unauthorised copying,
5 : // modification, distribution, or use of this file is strictly
6 : // prohibited without prior written permission from Flipdare Pty Ltd.
7 : //
8 : // This software includes third-party components licensed under MIT,
9 : // BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
10 : //
11 :
12 : import 'dart:math';
13 :
14 : import 'randomizer.dart';
15 : part 'default_randomizer.y.dart';
16 :
17 : const kDefaultRandomizer = DefaultRandomizer();
18 :
19 : /// NOTE: on `nextUniqueString` and `nextSecureString`
20 : ///
21 : /// Possible conflicts approximately equal to the √ S^l (Birthday Paradox)
22 : /// where S^l is the number of possible combinations.
23 : ///
24 : /// For alpha strings.
25 : ///
26 : /// Unique:
27 : /// ```
28 : /// S = 62 (approx)
29 : /// L = 16
30 : /// conflicts = 4.67x10^7
31 : /// ```
32 : ///
33 : /// Secure:
34 : /// ```
35 : /// S = 62 (approx)
36 : /// L = 16
37 : /// conflicts = 5.2x10^19
38 : /// ```
39 : ///
40 : class DefaultRandomizer extends Randomizer {
41 HIT 3 : static final Random rnd = Random();
42 :
43 1 : const DefaultRandomizer();
44 :
45 1 : @override
46 : bool nextBool() {
47 2 : return rnd.nextBool();
48 : }
49 :
50 : /// Process
51 : /// 1. Generate a random double between 0 (inclusive) and 1 (exclusive)
52 : /// 2. Scale it to the desired range size (max - min + 1)
53 : /// 3. Floor the result to get an integer
54 1 : @override
55 : int nextInt(int min, int max) {
56 1 : if (min >= max) {
57 2 : throw ArgumentError('min ($min) must be less than max ($max)');
58 : }
59 5 : return min + rnd.nextInt((max + 1) - min);
60 : }
61 :
62 1 : @override
63 : double nextDouble([double min = 0, double max = 1]) {
64 1 : if (min >= max) {
65 2 : throw ArgumentError('min ($min) must be less than max ($max)');
66 : }
67 :
68 : // Generate a random number between 0 (inclusive) and 1 (exclusive)
69 2 : final val = rnd.nextDouble();
70 :
71 : // Scale it to the desired range
72 3 : return min + (val * (max - min));
73 : }
74 :
75 1 : @override
76 : String nextString(int length) {
77 2 : var codeUnits = List.generate(length, (index) {
78 3 : return rnd.nextInt(33) + 89;
79 : });
80 :
81 1 : return String.fromCharCodes(codeUnits);
82 : }
83 :
84 1 : @override
85 : String nextSafeString(int length) {
86 : const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
87 7 : return List.generate(length, (index) => chars[rnd.nextInt(chars.length)]).join();
88 : }
89 :
90 1 : @override
91 : String nextPassPhrase(int length, [bool addNumbers = true, bool addSpecialChars = true]) {
92 1 : final List<String> wds = [];
93 :
94 : int charCt = 0;
95 : do {
96 6 : String wd = words[rnd.nextInt(words.length)];
97 2 : charCt += wd.length;
98 1 : wds.add(wd);
99 1 : } while (charCt < length);
100 :
101 1 : String passwd = wds.join('-');
102 :
103 : if (addNumbers) {
104 4 : passwd += rnd.nextInt(100).toString(); // Add a random number between 0 and 99
105 : }
106 : if (addSpecialChars) {
107 : const specialChars = '!@#\$%^&*()';
108 5 : passwd += specialChars[rnd.nextInt(specialChars.length)];
109 : }
110 :
111 : return passwd;
112 : }
113 :
114 MIS 0 : @override
115 : String? choice(List<String> items) {
116 0 : if (items.isEmpty) {
117 : return null;
118 : }
119 :
120 0 : return items[rnd.nextInt(items.length)];
121 : }
122 : }
|