DotNext by Roman Sakno

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

 RandomExtensions

public static class RandomExtensions
Provides random data generation.
using DotNext.Buffers; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; namespace DotNext { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class RandomExtensions { [System.Runtime.CompilerServices.NullableContext(0)] private interface IRandomStringGenerator { void NextString(Span<char> buffer, ReadOnlySpan<char> allowedChars); } [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.NullableContext(0)] private readonly struct PseudoRandomStringGenerator : IRandomStringGenerator { [System.Runtime.CompilerServices.Nullable(1)] private readonly Random rng; [System.Runtime.CompilerServices.NullableContext(1)] internal PseudoRandomStringGenerator(Random random) { rng = random; } void IRandomStringGenerator.NextString(Span<char> buffer, ReadOnlySpan<char> allowedChars) { ref char reference = ref MemoryMarshal.GetReference(allowedChars); Span<char> span = buffer; for (int i = 0; i < span.Length; i++) { span[i] = Unsafe.Add(ref reference, rng.Next(0, allowedChars.Length)); } } } [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.NullableContext(0)] private readonly struct RandomStringGenerator : IRandomStringGenerator { [System.Runtime.CompilerServices.Nullable(1)] private readonly RandomNumberGenerator rng; [System.Runtime.CompilerServices.NullableContext(1)] internal RandomStringGenerator(RandomNumberGenerator random) { rng = random; } unsafe void IRandomStringGenerator.NextString(Span<char> buffer, ReadOnlySpan<char> allowedChars) { int num = buffer.Length * 4; MemoryRental<byte> memoryRental; if (num > MemoryRental<byte>.StackallocThreshold) memoryRental = new MemoryRental<byte>(num); else { int num2 = num; memoryRental = new Span<byte>(stackalloc byte[(int)(uint)num2], num2); } MemoryRental<byte> memoryRental2 = memoryRental; try { rng.GetBytes(memoryRental2.Span); num = 0; ref char reference = ref MemoryMarshal.GetReference(allowedChars); Span<char> span = buffer; for (int num2 = 0; num2 < span.Length; num2++) { ref char reference2 = ref span[num2]; int elementOffset = (BitConverter.ToInt32(memoryRental2.Span.Slice(num)) & 2147483647) % allowedChars.Length; reference2 = Unsafe.Add(ref reference, elementOffset); num += 4; } } finally { memoryRental2.Dispose(); } } } internal static readonly int BitwiseHashSalt = new Random().Next(); [System.Runtime.CompilerServices.NullableContext(0)] [return: System.Runtime.CompilerServices.Nullable(1)] private unsafe static string NextString<TGenerator>(TGenerator generator, ReadOnlySpan<char> allowedChars, int length) where TGenerator : struct, IRandomStringGenerator { if (length < 0) throw new ArgumentOutOfRangeException("length"); if (length != 0 && !allowedChars.IsEmpty) { MemoryRental<char> memoryRental = (length <= MemoryRental<char>.StackallocThreshold) ? ((MemoryRental<char>)new Span<char>((void*)stackalloc byte[(int)checked(unchecked((ulong)(uint)length) * 2)], length)) : new MemoryRental<char>(length); MemoryRental<char> memoryRental2 = memoryRental; try { generator.NextString(memoryRental2.Span, allowedChars); return new string(memoryRental2.Span); } finally { memoryRental2.Dispose(); } } return string.Empty; } public static string NextString(this Random random, [System.Runtime.CompilerServices.Nullable(0)] ReadOnlySpan<char> allowedChars, int length) { return NextString(new PseudoRandomStringGenerator(random), 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, [System.Runtime.CompilerServices.Nullable(0)] ReadOnlySpan<char> allowedChars, int length) { return NextString(new RandomStringGenerator(random), 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) { return random.Next<int>() & 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); } [System.Runtime.CompilerServices.NullableContext(0)] public unsafe static T Next<[System.Runtime.CompilerServices.IsUnmanaged] T>([System.Runtime.CompilerServices.Nullable(1)] this Random random) where T : struct { T result = default(T); random.NextBytes(new Span<byte>((void*)(&result), sizeof(T))); return result; } [System.Runtime.CompilerServices.NullableContext(0)] public unsafe static T Next<[System.Runtime.CompilerServices.IsUnmanaged] T>([System.Runtime.CompilerServices.Nullable(1)] this RandomNumberGenerator random) where T : struct { T result = default(T); random.GetBytes(new Span<byte>((void*)(&result), sizeof(T))); return result; } } }