@anonympins/fingerprint 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/composer.json +8 -1
  4. package/package.json +1 -1
  5. package/public/fingerprint-wordpress.zip +0 -0
  6. package/src/js/build-client.js +8 -10
  7. package/src/js/fingerprint.builder.js +37 -38
  8. package/src/js/fingerprint.client.js +1531 -1463
  9. package/src/js/fingerprint.client.obfuscated.js +1 -0
  10. package/src/js/fingerprint.js +190 -16
  11. package/src/js/fingerprint.utils.js +213 -213
  12. package/src/js/library.js +340 -376
  13. package/src/js/mongodb-store.js +1 -1
  14. package/src/js/optimization.worker.js +27 -27
  15. package/src/js/pow.solver.inline.js +154 -56
  16. package/src/js/pow.solver.js +180 -92
  17. package/src/js/pow.worker.js +48 -48
  18. package/src/js/redis-store.js +1 -1
  19. package/src/js/tests/fingerprint.client.init.test.js +146 -143
  20. package/src/js/tests/fingerprint.test.js +124 -10
  21. package/src/js/tests/ip-reputation.test.js +1 -0
  22. package/src/js/upow-model-task.js +14 -15
  23. package/src/php/AutoTuner.php +34 -34
  24. package/src/php/Challenge/ChallengeUtils.php +57 -11
  25. package/src/php/Config/SecurityProfiles.php +20 -0
  26. package/src/php/DirectFingerprint.php +190 -145
  27. package/src/php/FingerprintBuilder.php +29 -30
  28. package/src/php/FingerprintClient.php +147 -148
  29. package/src/php/FingerprintEngine.php +44 -17
  30. package/src/php/Ja3AnomalyDetector.php +33 -32
  31. package/src/php/Optimization/FunctionRegistry.php +7 -7
  32. package/src/php/Optimization/Optimization.php +24 -24
  33. package/src/php/Optimization/OptimizationOperators.php +26 -25
  34. package/src/php/Optimization/ProblemInitializers.php +52 -52
  35. package/src/php/ProblemManager.php +31 -34
  36. package/src/php/RequestContext.php +8 -1
  37. package/src/php/Store/IStore.php +7 -8
  38. package/src/php/Store/InMemoryStore.php +66 -66
  39. package/src/php/Store/MongoDbStore.php +5 -5
  40. package/src/php/Store/RedisStore.php +5 -5
  41. package/src/php/Store/StoreManager.php +35 -35
  42. package/src/php/Tests/ChallengeUtilsTest.php +453 -453
  43. package/src/php/Tests/DnsCircuitBreakerTest.php +105 -105
  44. package/src/php/Tests/FingerprintEngineTest.php +38 -0
  45. package/src/php/Tests/IpReputationTest.php +10 -0
  46. package/src/php/Tests/MaliciousPatternsTest.php +103 -103
  47. package/src/php/Tests/MetricsTest.php +97 -97
  48. package/src/php/Tests/ProblemManagerTest.php +376 -376
  49. package/src/php/Tests/QuicFingerprintTest.php +53 -53
  50. package/src/php/Tests/RequestUtilsTest.php +471 -471
  51. package/src/php/Tests/TLSClientHelloParserTest.php +177 -177
  52. package/src/php/Tests/config/ed25519_key.json +3 -3
  53. package/src/php/Utils/BlockList.php +99 -99
  54. package/src/php/Utils/Env.php +49 -49
  55. package/src/php/Utils/MaliciousPatterns.php +74 -74
  56. package/src/php/Utils/MetricsManager.php +209 -209
  57. package/src/php/Utils/RequestUtils.php +129 -7
  58. package/src/php/Utils/TLSClientHelloParser.php +369 -369
  59. package/src/php/WordPress/WpDbStore.php +155 -0
  60. package/src/php/WordPress/fingerprint-wordpress.php +554 -0
  61. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.mo +0 -0
  62. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.po +262 -0
  63. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.mo +0 -0
  64. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.po +268 -0
  65. package/src/php/WordPress/package.php +218 -0
  66. package/src/php/bin/auto-tune.php +118 -118
@@ -5,7 +5,7 @@ declare(strict_types=1);
5
5
  namespace Anonympins\Fingerprint\Optimization;
6
6
 
7
7
  /**
8
- * Registre pour exposer de manière contrôlée les fonctions de la bibliothèque d'optimisation.
8
+ * Registry to safely expose optimization library routines to task runners.
9
9
  */
10
10
  class FunctionRegistry
11
11
  {
@@ -13,17 +13,17 @@ class FunctionRegistry
13
13
  private static array $functions = [];
14
14
 
15
15
  /**
16
- * Initialise le registre avec les fonctions disponibles.
16
+ * Initializes registry with built-in solvers and evaluators.
17
17
  */
18
18
  private static function initialize(): void
19
19
  {
20
20
  if (empty(self::$functions)) {
21
- // Fonctions de "Scoring"
21
+ // Evaluators & Scoring Adapters
22
22
  self::$functions['tsp.calculateEnergy'] = [OptimizationUtils::class, 'evaluatePathDistance'];
23
23
  self::$functions['portfolio.calculateMetrics'] = [OptimizationOperators::class, 'calculatePortfolioMetrics'];
24
24
  self::$functions['facility.calculateEnergy'] = [OptimizationOperators::class, 'evaluateFacilityLocation'];
25
25
 
26
- // Fonctions de "Résolution"
26
+ // Full Optimization Solvers
27
27
  self::$functions['tsp.solve'] = [OptimizationOperators::class, 'solveTSP'];
28
28
  self::$functions['portfolio.solve'] = [OptimizationOperators::class, 'solvePortfolio'];
29
29
  self::$functions['fraud.solve'] = [OptimizationOperators::class, 'solveFraudDetection'];
@@ -33,7 +33,7 @@ class FunctionRegistry
33
33
  }
34
34
 
35
35
  /**
36
- * Récupère une fonction depuis le registre.
36
+ * Retrieves a function from the registry.
37
37
  */
38
38
  public static function get(string $name): ?callable
39
39
  {
@@ -41,7 +41,7 @@ class FunctionRegistry
41
41
  return self::$functions[$name] ?? null;
42
42
  }
43
43
  /**
44
- * Enregistre une nouvelle fonction. Principalement pour les tests.
44
+ * Registers a custom function. Primarily intended for testing.
45
45
  * @internal
46
46
  * @param string $name
47
47
  * @param callable $function
@@ -54,7 +54,7 @@ class FunctionRegistry
54
54
  }
55
55
 
56
56
  /**
57
- * Réinitialise le registre. Uniquement pour les tests.
57
+ * Resets function registry. Intended for testing.
58
58
  * @internal
59
59
  */
60
60
  public static function __internal_resetRegistry(): void
@@ -5,12 +5,12 @@ declare(strict_types=1);
5
5
  namespace Anonympins\Fingerprint\Optimization;
6
6
 
7
7
  /**
8
- * Bibliothèque d'algorithmes d'optimisation.
8
+ * Optimization algorithms library.
9
9
  */
10
10
  class Optimization
11
11
  {
12
12
  /**
13
- * Génère un nombre flottant aléatoire cryptographiquement sûr entre 0 (inclus) et 1 (exclus).
13
+ * Generates a cryptographically secure random float in [0, 1).
14
14
  */
15
15
  private static function secureRandom(): float
16
16
  {
@@ -22,12 +22,12 @@ class Optimization
22
22
  }
23
23
 
24
24
  /**
25
- * Algorithme génétique multi-objectifs (inspiré de NSGA-II).
25
+ * Multi-objective genetic algorithm (inspired by NSGA-II).
26
26
  * @param callable $createIndividual
27
27
  * @param callable $fitnessFunction
28
28
  * @param callable $crossover
29
29
  * @param callable $mutate
30
- * @param array|null $currentConfig La configuration actuelle pour guider l'initialisation et la mutation.
30
+ * @param array|null $currentConfig Reference baseline configuration.
31
31
  * @param array $options
32
32
  * @return array<int, array{solution: mixed, objectives: array<float>}>
33
33
  */
@@ -35,8 +35,8 @@ class Optimization
35
35
  callable $createIndividual,
36
36
  callable $fitnessFunction,
37
37
  callable $crossover,
38
- callable $mutate, // La fonction mutate doit maintenant accepter $currentConfig
39
- ?array $currentConfig = null, // NOUVEAU: La configuration actuelle
38
+ callable $mutate, // The mutate function must accept $currentConfig
39
+ ?array $currentConfig = null, // Reference baseline configuration
40
40
  array $options = []
41
41
  ): array {
42
42
  $generations = $options['generations'] ?? 150;
@@ -53,14 +53,14 @@ class Optimization
53
53
  }
54
54
 
55
55
  for ($gen = 0; $gen < $generations; $gen++) {
56
- // 1. Créer une population d'enfants
56
+ // 1. Generate offspring population
57
57
  $offspring = [];
58
58
  for ($i = 0; $i < $populationSize; $i++) {
59
59
  $parent1 = $population[random_int(0, count($population) - 1)];
60
60
  $parent2 = $population[random_int(0, count($population) - 1)];
61
61
  $childIndividual = $crossover($parent1['individual'], $parent2['individual']);
62
62
  if (self::secureRandom() < $mutationRate) {
63
- $childIndividual = $mutate($childIndividual, $currentConfig); // Passer $currentConfig à mutate
63
+ $childIndividual = $mutate($childIndividual, $currentConfig);
64
64
  }
65
65
  $offspring[] = [
66
66
  'individual' => $childIndividual,
@@ -68,20 +68,20 @@ class Optimization
68
68
  ];
69
69
  }
70
70
 
71
- // 2. Combiner parents et enfants
71
+ // 2. Combine parent and offspring populations
72
72
  $combinedPopulation = array_merge($population, $offspring);
73
73
 
74
- // 3. Trier la population combinée en fronts
74
+ // 3. Sort into non-dominated Pareto fronts
75
75
  $fronts = self::nonDominatedSort($combinedPopulation);
76
76
 
77
- // 4. Construire la nouvelle population
77
+ // 4. Build next generation
78
78
  $newPopulation = [];
79
79
  foreach ($fronts as $front) {
80
80
  if (count($newPopulation) + count($front) <= $populationSize) {
81
81
  $newPopulation = array_merge($newPopulation, $front);
82
82
  } else {
83
83
  self::calculateCrowdingDistance($front);
84
- // Trier par distance décroissante
84
+ // Sort by crowding distance descending
85
85
  usort($front, fn ($a, $b) => $b['crowdingDistance'] <=> $a['crowdingDistance']);
86
86
  $remaining = $populationSize - count($newPopulation);
87
87
  $newPopulation = array_merge($newPopulation, array_slice($front, 0, $remaining));
@@ -91,11 +91,11 @@ class Optimization
91
91
  $population = $newPopulation;
92
92
  }
93
93
 
94
- // Retourner le premier front de la population finale
94
+ // Return the first non-dominated front of the final population
95
95
  $finalFronts = self::nonDominatedSort($population);
96
96
  $bestFront = $finalFronts[0] ?? [];
97
97
 
98
- // Filtrer pour ne garder que les solutions avec des objectifs uniques
98
+ // Deduplicate solutions with identical objective scores
99
99
  $uniqueSolutionsMap = [];
100
100
  foreach ($bestFront as $p) {
101
101
  $key = json_encode($p['objectives']);
@@ -110,7 +110,7 @@ class Optimization
110
110
  }
111
111
 
112
112
  /**
113
- * Détermine si la solution A domine la solution B.
113
+ * Determines whether solution A Pareto-dominates solution B (minimization).
114
114
  * @param array<float> $objectivesA
115
115
  * @param array<float> $objectivesB
116
116
  */
@@ -119,17 +119,17 @@ class Optimization
119
119
  $aIsBetterInOne = false;
120
120
  for ($i = 0; $i < count($objectivesA); $i++) {
121
121
  if ($objectivesA[$i] > $objectivesB[$i]) {
122
- return false; // A est pire sur au moins un objectif
122
+ return false; // A is worse on at least one objective
123
123
  }
124
124
  if ($objectivesA[$i] < $objectivesB[$i]) {
125
- $aIsBetterInOne = true; // A est strictement meilleur sur au moins un
125
+ $aIsBetterInOne = true; // A is strictly better on at least one objective
126
126
  }
127
127
  }
128
128
  return $aIsBetterInOne;
129
129
  }
130
130
 
131
131
  /**
132
- * Trie une population en fronts de Pareto non-dominés.
132
+ * Sorts population into non-dominated Pareto fronts (NSGA-II).
133
133
  * @param array<int, array> &$populationWithObjectives
134
134
  * @return array<int, array>
135
135
  */
@@ -182,7 +182,7 @@ class Optimization
182
182
  }
183
183
 
184
184
  /**
185
- * Calcule la distance de promiscuité (crowding distance) pour un front.
185
+ * Computes crowding distance for a front to preserve diversity.
186
186
  * @param array<int, array> &$front
187
187
  */
188
188
  private static function calculateCrowdingDistance(array &$front): void
@@ -197,13 +197,13 @@ class Optimization
197
197
  }
198
198
 
199
199
  for ($i = 0; $i < $numObjectives; $i++) {
200
- // Trier le front par l'objectif courant
200
+ // Sort front by current objective
201
201
  usort($front, fn ($a, $b) => $a['objectives'][$i] <=> $b['objectives'][$i]);
202
202
 
203
203
  $minObj = $front[0]['objectives'][$i];
204
204
  $maxObj = $front[$l - 1]['objectives'][$i];
205
205
 
206
- // Les solutions aux extrémités ont une distance infinie
206
+ // Boundary solutions receive infinite distance to encourage spread
207
207
  $front[0]['crowdingDistance'] = INF;
208
208
  $front[$l - 1]['crowdingDistance'] = INF;
209
209
 
@@ -218,11 +218,11 @@ class Optimization
218
218
  }
219
219
 
220
220
  /**
221
- * Calcule la déviation d'une série de chiffres par rapport à la loi de Benford.
222
- * @public
221
+ * Calculates deviation from Benford's Law distribution.
222
+ * Elevated values indicate synthetic or automated intervals.
223
223
  * @param array<int|float> $numbers
224
224
  */
225
- public static function benfordTest(array $numbers): float // Rendre la méthode publique et statique
225
+ public static function benfordTest(array $numbers): float // Public static helper for digit distribution test
226
226
  {
227
227
  $counts = array_fill(1, 9, 0);
228
228
  $validCount = 0;
@@ -5,14 +5,14 @@ declare(strict_types=1);
5
5
  namespace Anonympins\Fingerprint\Optimization;
6
6
 
7
7
  /**
8
- * Opérateurs pour les problèmes d'optimisation.
8
+ * Operators and objective function factories for optimization problems.
9
9
  */
10
10
  class OptimizationOperators
11
11
  {
12
12
  /**
13
- * Crée une fonction de sélection par tournoi pour un algorithme génétique.
14
- * @param array $options Options pour le tournoi.
15
- * @return callable Une fonction de sélection.
13
+ * Creates a tournament selection operator for genetic algorithms.
14
+ * @param array $options Tournament configuration options.
15
+ * @return callable Selection operator function.
16
16
  */
17
17
  public static function createTournamentSelection(array $options = []): callable
18
18
  {
@@ -37,7 +37,7 @@ class OptimizationOperators
37
37
  }
38
38
 
39
39
  /**
40
- * Génère un nombre flottant aléatoire cryptographiquement sûr entre 0 (inclus) et 1 (exclus).
40
+ * Generates a cryptographically secure random float in [0, 1).
41
41
  */
42
42
  private static function secureRandom(): float
43
43
  {
@@ -49,7 +49,7 @@ class OptimizationOperators
49
49
  }
50
50
 
51
51
  /**
52
- * Évalue un portefeuille pour un payload donné.
52
+ * Evaluates a portfolio for a given payload.
53
53
  *
54
54
  * @param array $weights
55
55
  * @param array $payload
@@ -62,22 +62,21 @@ class OptimizationOperators
62
62
  }
63
63
 
64
64
  /**
65
- * Crée un évaluateur pour l'optimisation de portefeuille.
65
+ * Creates a portfolio allocation evaluator.
66
66
  * @param array $config
67
67
  * @return callable
68
68
  */
69
69
  public static function createPortfolioAllocator(array $config): callable
70
70
  {
71
- // Cette fonction est un placeholder. Une implémentation complète nécessiterait
72
- // une logique de calcul de rendement et de volatilité de portefeuille.
71
+ // Baseline portfolio evaluator minimizing negative expected return
73
72
  return function (array $weights) use ($config): float {
74
- // Minimiser le rendement négatif (donc maximiser le rendement)
73
+ // Minimize negative return (maximizes positive return)
75
74
  return -array_sum($weights);
76
75
  };
77
76
  }
78
77
 
79
78
  /**
80
- * Crée un évaluateur pour l'auto-tuning complet de la configuration de sécurité.
79
+ * Creates an evaluator for full security configuration auto-tuning.
81
80
  * @param array $context
82
81
  * @return callable
83
82
  */
@@ -145,6 +144,7 @@ class OptimizationOperators
145
144
  ];
146
145
 
147
146
  // 1. Évaluation sur les logs de trafic réels
147
+ // 1. Evaluate on real traffic logs
148
148
  foreach ($trafficData as $log) {
149
149
  $weight = (float)($log['weight'] ?? 1.0);
150
150
  $confidence = ($confidenceWeights[$log['type'] ?? ''] ?? 1.0) * $weight;
@@ -206,6 +206,7 @@ class OptimizationOperators
206
206
  }
207
207
 
208
208
  // 3. Pénalité de dérive d'échelle (L2 Regularization par rapport au profil d'origine)
209
+ // 3. Scale drift penalty (L2 regularization against baseline profile)
209
210
  $regularizationPenalty = 0.0;
210
211
  if ($currentConfig && isset($currentConfig['weights'])) {
211
212
  foreach ($config['weights'] as $key => $val) {
@@ -215,6 +216,7 @@ class OptimizationOperators
215
216
  }
216
217
 
217
218
  // 4. Maximisation de la marge
219
+ // 4. Margin separation maximization
218
220
  $marginOverlap = max(0.0, $maxHumanScore - $minBotScore);
219
221
  $marginPenalty = $marginOverlap / 100.0;
220
222
 
@@ -226,7 +228,7 @@ class OptimizationOperators
226
228
  }
227
229
 
228
230
  /**
229
- * Résout le problème de l'auto-tuning complet de la configuration de sécurité.
231
+ * Solves end-to-end security configuration auto-tuning.
230
232
  * @param array $context
231
233
  * @param array $options
232
234
  * @return array
@@ -256,7 +258,7 @@ class OptimizationOperators
256
258
  if (isset($config[$section]) && is_array($config[$section])) {
257
259
  foreach ($config[$section] as $k => $v) {
258
260
  if (is_numeric($v)) {
259
- $randomVariation = 1.0 + (self::secureRandom() - 0.5) * 0.5; // Variation de +/- 25%
261
+ $randomVariation = 1.0 + (self::secureRandom() - 0.5) * 0.5; // +/- 25% variation
260
262
  $ind[$section][$k] = $v * $randomVariation;
261
263
  } else {
262
264
  $ind[$section][$k] = $v;
@@ -330,7 +332,7 @@ class OptimizationOperators
330
332
  }
331
333
 
332
334
  /**
333
- * Crée un évaluateur pour trouver les seuils de détection de fraude optimaux.
335
+ * Creates an evaluator to find optimal fraud detection thresholds.
334
336
  * @param array $context
335
337
  * @return callable
336
338
  */
@@ -374,7 +376,7 @@ class OptimizationOperators
374
376
  }
375
377
 
376
378
  /**
377
- * Résout le problème de la détection de fraude.
379
+ * Solves fraud detection threshold optimization.
378
380
  * @param array $context
379
381
  * @param array $options
380
382
  * @return array
@@ -411,19 +413,18 @@ class OptimizationOperators
411
413
  }
412
414
 
413
415
  /**
414
- * Placeholder pour le solveur TSP.
416
+ * TSP solver baseline implementation.
415
417
  * @param array $cities
416
418
  * @param array $options
417
419
  * @return array
418
420
  */
419
421
  public static function solveTSP(array $cities, array $options = []): array
420
422
  {
421
- // Implémentation factice pour la complétude
422
423
  return ['solution' => array_keys($cities), 'energy' => 100];
423
424
  }
424
425
 
425
426
  /**
426
- * Placeholder pour le solveur de portefeuille.
427
+ * Portfolio allocator baseline implementation.
427
428
  * @param array $assets
428
429
  * @param float $maxVolatility
429
430
  * @param array $options
@@ -431,7 +432,6 @@ class OptimizationOperators
431
432
  */
432
433
  public static function solvePortfolio(array $assets, float $maxVolatility, array $options = []): array
433
434
  {
434
- // Implémentation factice pour la complétude
435
435
  return ['solution' => array_fill(0, count($assets), 1 / count($assets)), 'fitness' => -0.1];
436
436
  }
437
437
 
@@ -440,7 +440,7 @@ class OptimizationOperators
440
440
  $fixedCostPerFacility = $options['fixedCostPerFacility'] ?? 0;
441
441
  $initialTemperature = $options['initialTemperature'] ?? 100000.0;
442
442
  $coolingRate = $options['coolingRate'] ?? 0.999;
443
- $maxIterations = $options['maxIterations'] ?? 15000; // Borne raisonnable pour PHP
443
+ $maxIterations = $options['maxIterations'] ?? 15000;
444
444
 
445
445
  $evaluator = function (array $facilities) use ($customers, $fixedCostPerFacility): float {
446
446
  $totalConnectionCost = 0.0;
@@ -473,6 +473,7 @@ class OptimizationOperators
473
473
  };
474
474
 
475
475
  // Génération d'une solution initiale aléatoire
476
+ // Random initial placement
476
477
  $currentSolution = [];
477
478
  for ($i = 0; $i < $numFacilities; $i++) {
478
479
  $currentSolution[] = [
@@ -509,12 +510,12 @@ class OptimizationOperators
509
510
  }
510
511
 
511
512
  /**
512
- * Évalue de manière indépendante l'énergie d'une solution de placement d'infrastructures.
513
- * Appelée par le serveur pour valider les calculs soumis par le client.
513
+ * Independently evaluates total cost of a facility placement proposal.
514
+ * Invoked server-side to verify client-submitted solutions.
514
515
  *
515
- * @param array $facilities Liste des positions proposées par le client.
516
- * @param array $payload Configuration initiale contenant les clients et les coûts fixes.
517
- * @return float Le coût total vérifié.
516
+ * @param array $facilities Facility coordinates proposed by client.
517
+ * @param array $payload Base payload containing customer coordinates and fixed costs.
518
+ * @return float Verified total connection and maintenance cost.
518
519
  */
519
520
  public static function evaluateFacilityLocation(array $facilities, array $payload): float
520
521
  {
@@ -1,53 +1,53 @@
1
- <?php
2
-
3
- declare(strict_types=1);
4
-
5
- namespace Anonympins\Fingerprint\Optimization;
6
-
7
- /**
8
- * Fonctions pour générer dynamiquement les données d'un problème.
9
- */
10
- class ProblemInitializers
11
- {
12
- /** @var array<string, callable> */
13
- private static array $initializers = [];
14
-
15
- private static function initialize(): void
16
- {
17
- if (empty(self::$initializers)) {
18
- self::$initializers['generate:randomPoints'] = function (array $params): array {
19
- $count = $params['count'] ?? 0;
20
- $bounds = $params['bounds'] ?? ['x' => 1000, 'y' => 1000];
21
- if (!is_numeric($count)) return [];
22
- $points = [];
23
- for ($i = 0; $i < $count; $i++) {
24
- $points[] = [
25
- 'x' => mt_rand() / mt_getrandmax() * $bounds['x'],
26
- 'y' => mt_rand() / mt_getrandmax() * $bounds['y']
27
- ];
28
- }
29
- return $points;
30
- };
31
-
32
- self::$initializers['generate:randomAssets'] = function (array $params): array {
33
- $count = $params['count'] ?? 0;
34
- if (!is_numeric($count)) return [];
35
- $assets = [];
36
- for ($i = 0; $i < $count; $i++) {
37
- $assets[] = [
38
- 'name' => 'Asset ' . ($i + 1),
39
- 'expectedReturn' => mt_rand() / mt_getrandmax() * 0.2,
40
- 'volatility' => 0.1 + mt_rand() / mt_getrandmax() * 0.3
41
- ];
42
- }
43
- return $assets;
44
- };
45
- }
46
- }
47
-
48
- public static function get(string $name): ?callable
49
- {
50
- self::initialize();
51
- return self::$initializers[$name] ?? null;
52
- }
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Anonympins\Fingerprint\Optimization;
6
+
7
+ /**
8
+ * Generators for dynamically seeding problem instance datasets.
9
+ */
10
+ class ProblemInitializers
11
+ {
12
+ /** @var array<string, callable> */
13
+ private static array $initializers = [];
14
+
15
+ private static function initialize(): void
16
+ {
17
+ if (empty(self::$initializers)) {
18
+ self::$initializers['generate:randomPoints'] = function (array $params): array {
19
+ $count = $params['count'] ?? 0;
20
+ $bounds = $params['bounds'] ?? ['x' => 1000, 'y' => 1000];
21
+ if (!is_numeric($count)) return [];
22
+ $points = [];
23
+ for ($i = 0; $i < $count; $i++) {
24
+ $points[] = [
25
+ 'x' => mt_rand() / mt_getrandmax() * $bounds['x'],
26
+ 'y' => mt_rand() / mt_getrandmax() * $bounds['y']
27
+ ];
28
+ }
29
+ return $points;
30
+ };
31
+
32
+ self::$initializers['generate:randomAssets'] = function (array $params): array {
33
+ $count = $params['count'] ?? 0;
34
+ if (!is_numeric($count)) return [];
35
+ $assets = [];
36
+ for ($i = 0; $i < $count; $i++) {
37
+ $assets[] = [
38
+ 'name' => 'Asset ' . ($i + 1),
39
+ 'expectedReturn' => mt_rand() / mt_getrandmax() * 0.2,
40
+ 'volatility' => 0.1 + mt_rand() / mt_getrandmax() * 0.3
41
+ ];
42
+ }
43
+ return $assets;
44
+ };
45
+ }
46
+ }
47
+
48
+ public static function get(string $name): ?callable
49
+ {
50
+ self::initialize();
51
+ return self::$initializers[$name] ?? null;
52
+ }
53
53
  }