DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="0.9.0" />

 RandomExtensions

public static class RandomExtensions
Provides random data generation.
using System; using System.Security.Cryptography; namespace DotNext { public static class RandomExtensions { private interface IRandomCharacterGenerator { char NextChar(ReadOnlySpan<char> allowedChars); } private readonly struct RandomCharacterGenerator : IRandomCharacterGenerator { private readonly Random random; internal RandomCharacterGenerator(Random random) { this.random = random; } char IRandomCharacterGenerator.NextChar(ReadOnlySpan<char> allowedChars) { return allowedChars[random.Next(0, allowedChars.Length)]; } } private readonly struct RNGCharacterGenerator : IRandomCharacterGenerator { private readonly byte[] buffer; private readonly RandomNumberGenerator random; internal RNGCharacterGenerator(RandomNumberGenerator random) { this.random = random; buffer = new byte[4]; } char IRandomCharacterGenerator.NextChar(ReadOnlySpan<char> allowedChars) { random.GetBytes(buffer, 0, 4); int index = (BitConverter.ToInt32(buffer, 0) & 2147483647) % allowedChars.Length; return allowedChars[index]; } } internal static readonly int BitwiseHashSalt = new Random().Next(); private unsafe static string NextString<R>(ref R generator, ReadOnlySpan<char> allowedChars, int length) where R : struct, IRandomCharacterGenerator { if (length < 0) throw new ArgumentOutOfRangeException("length"); if (length != 0) { Span<char> span = (length < 1024) ? new Span<char>((void*)stackalloc byte[(int)checked(unchecked((ulong)(uint)length) * 2)], length) : new Span<char>(new char[length]); Span<char> span2 = span; for (int i = 0; i < span2.Length; i++) { span2[i] = generator.NextChar(allowedChars); } fixed (char* value = &span.GetPinnableReference()) { return new string(value, 0, length); } } return ""; } public static string NextString(this Random random, ReadOnlySpan<char> allowedChars, int length) { RandomCharacterGenerator generator = new RandomCharacterGenerator(random); return NextString(ref generator, allowedChars, length); } public static string NextString(this Random random, char[] allowedChars, int length) { return random.NextString(new ReadOnlySpan<char>(allowedChars), length); } public static string NextString(this Random random, string allowedChars, int length) { return random.NextString(allowedChars.AsSpan(), length); } public static string NextString(this RandomNumberGenerator random, ReadOnlySpan<char> allowedChars, int length) { RNGCharacterGenerator generator = new RNGCharacterGenerator(random); return NextString(ref generator, allowedChars, length); } public static string NextString(this RandomNumberGenerator random, char[] allowedChars, int length) { return random.NextString(new ReadOnlySpan<char>(allowedChars), length); } public static string NextString(this RandomNumberGenerator random, string allowedChars, int length) { return random.NextString(allowedChars.AsSpan(), length); } public static bool NextBoolean(this Random random, double trueProbability = 0.5) { if (!trueProbability.Between(0, 1, BoundType.Closed)) throw new ArgumentOutOfRangeException("trueProbability"); return random.NextDouble() >= 1 - trueProbability; } public static int Next(this RandomNumberGenerator random) { byte[] array = new byte[4]; random.GetBytes(array, 0, 4); return BitConverter.ToInt32(array, 0) & 2147483647; } public static bool NextBoolean(this RandomNumberGenerator random, double trueProbability = 0.5) { if (!trueProbability.Between(0, 1, BoundType.Closed)) throw new ArgumentOutOfRangeException("trueProbability"); return random.NextDouble() >= 1 - trueProbability; } public static double NextDouble(this RandomNumberGenerator random) { double num = (double)random.Next(); return num / (num + 1); } } }