//****************************************************************************************************** // Random.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 01/04/2006 - J. Ritchie Carroll // Generated original version of source code. // 09/17/2008 - J. Ritchie Carroll // Converted to C#. // 02/16/2009 - Josh L. Patterson // Edited Code Comments. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 12/14/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Security.Cryptography; namespace GSF.Security.Cryptography { /// /// Generates cryptographically strong random numbers. /// public static class Random { private static readonly RNGCryptoServiceProvider RandomNumberGenerator = new RNGCryptoServiceProvider(); /// /// Generates a cryptographically strong double-precision floating-point random number between zero and one. /// /// The cryptographic service provider (CSP) cannot be acquired. public static double Number { get { unchecked { return UInt32 / (uint.MaxValue + 1.0D); } } } /// /// Generates a cryptographically strong random decimal between zero and one. /// /// The cryptographic service provider (CSP) cannot be acquired. public static decimal Decimal { get { unchecked { return UInt64 / (ulong.MaxValue + 1.0M); } } } /// /// Generates a cryptographically strong random integer between specified values. /// /// A that is the low end of our range. /// A that is the high end of our range. /// The cryptographic service provider (CSP) cannot be acquired. /// A that is generated between the and the , or an excception. public static double Between(double startNumber, double stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return Number * (stopNumber - startNumber) + startNumber; } /// /// Fills an array of bytes with a cryptographically strong sequence of random values. /// /// The array to fill with a cryptographically strong sequence of random values. /// /// The length of the byte array determines how many cryptographically strong random bytes are produced. /// This method is thread safe. /// /// The cryptographic service provider (CSP) cannot be acquired. /// buffer is null. public static void GetBytes(byte[] buffer) { RandomNumberGenerator.GetBytes(buffer); } /// /// Generates a cryptographically strong random boolean (i.e., a coin toss). /// /// The cryptographic service provider (CSP) cannot be acquired. public static bool Boolean { get { byte[] value = new byte[1]; RandomNumberGenerator.GetBytes(value); return value[0] % 2 == 0; } } /// /// Generates a cryptographically strong 8-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static byte Byte { get { byte[] value = new byte[1]; RandomNumberGenerator.GetBytes(value); return value[0]; } } /// /// Generates a cryptographically strong 8-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static byte ByteBetween(byte startNumber, byte stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (byte)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong 16-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static short Int16 { get { byte[] value = new byte[2]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToInt16(value, 0); } } /// /// Generates a cryptographically strong 16-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static short Int16Between(short startNumber, short stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (short)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong unsigned 16-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static ushort UInt16 { get { byte[] value = new byte[2]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToUInt16(value, 0); } } /// /// Generates a cryptographically strong unsigned 16-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static ushort UInt16Between(ushort startNumber, ushort stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (ushort)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong 24-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static Int24 Int24 { get { byte[] value = new byte[3]; RandomNumberGenerator.GetBytes(value); return Int24.GetValue(value, 0); } } /// /// Generates a cryptographically strong 24-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static Int24 Int24Between(Int24 startNumber, Int24 stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (Int24)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong unsigned 24-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static UInt24 UInt24 { get { byte[] value = new byte[3]; RandomNumberGenerator.GetBytes(value); return UInt24.GetValue(value, 0); } } /// /// Generates a cryptographically strong unsigned 24-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static UInt24 Int24Between(UInt24 startNumber, UInt24 stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (UInt24)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong 32-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static int Int32 { get { byte[] value = new byte[4]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToInt32(value, 0); } } /// /// Generates a cryptographically strong 32-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static int Int32Between(int startNumber, int stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (int)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong unsigned 32-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static uint UInt32 { get { byte[] value = new byte[4]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToUInt32(value, 0); } } /// /// Generates a cryptographically strong unsigned 32-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static uint UInt32Between(uint startNumber, uint stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (uint)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong 64-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static long Int64 { get { byte[] value = new byte[8]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToInt64(value, 0); } } /// /// Generates a cryptographically strong 64-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static long Int64Between(long startNumber, long stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (long)(Number * (stopNumber - startNumber) + startNumber); } /// /// Generates a cryptographically strong unsigned 64-bit random integer. /// /// The cryptographic service provider (CSP) cannot be acquired. public static ulong UInt64 { get { byte[] value = new byte[8]; RandomNumberGenerator.GetBytes(value); return BitConverter.ToUInt64(value, 0); } } /// /// Generates a cryptographically strong unsigned 64-bit random integer between specified values. /// /// The cryptographic service provider (CSP) cannot be acquired. /// A that is the low end of our range. /// A that is the high end of our range. /// A that is generated between the and the . public static ulong UInt64Between(ulong startNumber, ulong stopNumber) { if (stopNumber < startNumber) throw new ArgumentException("stopNumber must be greater than startNumber"); return (ulong)(Number * (stopNumber - startNumber) + startNumber); } } }