code/CryptoRandom.ps1
using namespace System.Security.Cryptography; class CryptoRandom : Random { [RandomNumberGenerator] $RNG CryptoRandom() { $this.RNG = [RandomNumberGenerator]::Create() } [void] NextBytes([byte[]] $Buffer) { $this.RNG.GetBytes($Buffer) } [double] NextDouble() { $Buffer = [byte[]]::new(4) $this.NextBytes($Buffer); #return [BitConverter]::ToUInt32($Buffer, 0) / (1.0d + [UInt32]::MaxValue); return [BitConverter]::ToUInt32($Buffer, 0) / [double][UInt32]::MaxValue; } [int] Next([int] $MinValue, [int] $MaxValue) { if ($MinValue -lt 0) { throw [ArgumentOutOfRangeException]("MinValue must be 0 or greater. Received $MinValue."); } if ($MaxValue -lt 0) { throw [ArgumentOutOfRangeException]("MaxValue must be 0 or greater. Received $MaxValue."); } if ($MinValue -gt $MaxValue) { throw [ArgumentOutOfRangeException]("MinValue must be less than NaxValue. Received $MinValue and $MaxValue.") } if ($MinValue -eq $MaxValue) { return $MinValue } # original: $Range = [long]$MaxValue - $MinValue; # don't think the cast to [long] this is necessary $Range = $MaxValue - $MinValue; # same here - removed the cast to [long] return [int]([Math]::Floor($this.NextDouble() * $Range) + $MinValue) } [int] Next() { return $this.Next(0, [int]::MaxValue); } [int] Next([int] $MaxValue) { if ($MaxValue -lt 0) { throw [ArgumentOutOfRangeException]("MaxValue must be greater than zero. Received $MaxValue."); } return $this.Next(0, $MaxValue); } } |