| File: CryptoRandom.cs | Web Access |
| Project: src\sdk\src\TemplateEngine\Microsoft.TemplateEngine.Orchestrator.RunnableProjects\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj (Microsoft.TemplateEngine.Orchestrator.RunnableProjects) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Security.Cryptography; namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects { internal class CryptoRandom : IDisposable { private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); private readonly byte[] _uint32Buffer = new byte[4]; public CryptoRandom() { } #pragma warning disable IDE0060 // Remove unused parameter public CryptoRandom(int ignoredSeed) { } #pragma warning restore IDE0060 // Remove unused parameter public static int NextInt(int minValue, int maxValue) { using CryptoRandom random = new CryptoRandom(); return random.Next(minValue, maxValue); } public int Next() { _rng.GetBytes(_uint32Buffer); return BitConverter.ToInt32(_uint32Buffer, 0) & 0x7FFFFFFF; } public int Next(int maxValue) { if (maxValue < 0) { throw new ArgumentOutOfRangeException(nameof(maxValue)); } return Next(0, maxValue); } public int Next(int minValue, int maxValue) { if (minValue > maxValue) { throw new ArgumentOutOfRangeException(nameof(minValue)); } if (minValue == maxValue) { return minValue; } long diff = maxValue - minValue; // We are avoiding remainder bias by discarding the remainder. // background: https://ericlippert.com/2013/12/16/how-much-bias-is-introduced-by-the-remainder-technique/ while (true) { _rng.GetBytes(_uint32Buffer); uint rand = BitConverter.ToUInt32(_uint32Buffer, 0); long max = 1 + (long)uint.MaxValue; long remainder = max % diff; if (rand < max - remainder) { return (int)(minValue + (rand % diff)); } } } public double NextDouble() { _rng.GetBytes(_uint32Buffer); uint rand = BitConverter.ToUInt32(_uint32Buffer, 0); return rand / (1.0 + uint.MaxValue); } public void NextBytes(byte[] buffer) { buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); _rng.GetBytes(buffer); } public void Dispose() { _rng.Dispose(); } } }