< Summary

Information
Class: ArturRios.Util.Random.CustomRandom
Assembly: ArturRios.Util
File(s): D:\Repositories\dotnet-util\src\Random\CustomRandom.cs
Line coverage
87%
Covered lines: 57
Uncovered lines: 8
Coverable lines: 65
Total lines: 124
Line coverage: 87.6%
Branch coverage
86%
Covered branches: 19
Total branches: 22
Branch coverage: 86.3%
Method coverage
100%
Covered methods: 3
Fully covered methods: 0
Total methods: 3
Method coverage: 100%
Full method coverage: 0%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
NumberFromRng(...)75%4475%
NumberFromSystemRandom(...)75%4475%
Text(...)92.85%141495.12%

File(s)

D:\Repositories\dotnet-util\src\Random\CustomRandom.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using System.Text;
 3using ArturRios.Util.Collections;
 4
 5namespace ArturRios.Util.Random;
 6
 7/// <summary>
 8/// Provides helpers for generating random numbers and strings with optional exclusion constraints.
 9/// </summary>
 10public static class CustomRandom
 11{
 12    /// <summary>
 13    /// Generates a cryptographically strong random integer between <paramref name="start"/> (inclusive) and <paramref n
 14    /// </summary>
 15    /// <param name="start">Minimum value (inclusive).</param>
 16    /// <param name="end">Maximum value (inclusive).</param>
 17    /// <param name="differentFrom">Optional value to avoid returning; regeneration occurs until distinct.</param>
 18    /// <returns>A random integer in the specified range.</returns>
 19    public static int NumberFromRng(int start, int end, int? differentFrom = null)
 220    {
 221        end++;
 22
 223        var random = RandomNumberGenerator.GetInt32(start, end);
 24
 225        if (differentFrom is null)
 126        {
 127            return random;
 28        }
 29
 130        while (random == differentFrom)
 031        {
 032            random = RandomNumberGenerator.GetInt32(start, end);
 033        }
 34
 135        return random;
 236    }
 37
 38    /// <summary>
 39    /// Generates a random integer using <see cref="System.Random"/> between <paramref name="start"/> (inclusive) and <p
 40    /// </summary>
 41    /// <param name="start">Minimum value (inclusive).</param>
 42    /// <param name="end">Maximum value (exclusive).</param>
 43    /// <param name="differentFrom">Optional value to avoid returning; regeneration occurs until distinct.</param>
 44    /// <returns>A random integer in the specified range.</returns>
 45    public static int NumberFromSystemRandom(int start, int end, int? differentFrom = null)
 246    {
 247        System.Random rng = new();
 48
 249        var random = rng.Next(start, end);
 50
 251        if (differentFrom is null)
 152        {
 153            return random;
 54        }
 55
 156        while (random == differentFrom)
 057        {
 058            random = rng.Next(start, end);
 059        }
 60
 161        return random;
 262    }
 63
 64    /// <summary>
 65    /// Generates a random string respecting the constraints defined in <paramref name="options"/>.
 66    /// </summary>
 67    /// <param name="options">Options controlling length and character inclusion.</param>
 68    /// <param name="differentFrom">Optional collection of strings to exclude from results.</param>
 69    /// <returns>A randomly generated string.</returns>
 70    public static string Text(RandomStringOptions options, string[]? differentFrom = null)
 371    {
 372        while (true)
 373        {
 374            var random = new System.Random();
 375            var password = new StringBuilder();
 76
 377            var charCollectionCount = 0;
 78
 379            if (options.IncludeLowercase)
 380            {
 381                password.Append(Characters.LowerLetters[random.Next(Characters.LowerLetters.Length)]);
 382                charCollectionCount++;
 383            }
 84
 385            if (options.IncludeUppercase)
 386            {
 387                password.Append(Characters.UpperLetters[random.Next(Characters.UpperLetters.Length)]);
 388                charCollectionCount++;
 389            }
 90
 391            if (options.IncludeSpecialCharacters)
 392            {
 393                password.Append(Characters.Special[random.Next(Characters.Special.Length)]);
 394                charCollectionCount++;
 395            }
 96
 397            if (options.IncludeDigits)
 398            {
 399                password.Append(Characters.Digits[random.Next(Characters.Digits.Length)]);
 3100                charCollectionCount++;
 3101            }
 102
 144103            for (var i = charCollectionCount; i < options.Length; i++)
 69104            {
 69105                password.Append(Characters.All[random.Next(Characters.All.Length)]);
 69106            }
 107
 84108            var generatedString = new string(password.ToString().OrderBy(_ => random.Next()).ToArray());
 3109            var matchesExcludedString = false;
 110
 3111            if (differentFrom != null)
 1112            {
 4113                matchesExcludedString = differentFrom.Any(excludedString => excludedString.Equals(generatedString));
 1114            }
 115
 3116            if (matchesExcludedString)
 0117            {
 0118                continue;
 119            }
 120
 3121            return generatedString;
 122        }
 3123    }
 124}