//******************************************************************************************************
// 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);
}
}
}