Created
June 27, 2015 04:09
-
-
Save dwcullop/cb6e4901fcffcdf72f12 to your computer and use it in GitHub Desktop.
Cryptographically Secure Random Number Generator with a bunch of useful functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Security.Cryptography; | |
namespace DareWare.Utils | |
{ | |
#region Enum Types | |
[Flags] | |
public enum RandomCharSets | |
{ | |
None = 0x0000, | |
UpperCase = 0x0001, | |
LowerCase = 0x0002, | |
Numbers = 0x0004, | |
Symbols = 0x0008, | |
SymbolsExt = 0x0010, | |
ExtraPunc = 0x0020, | |
Currency = 0x0040, | |
GreekUpper = 0x0080, | |
GreekLower = 0x0100, | |
Dingbats = 0x0200, | |
CircleNums = 0x0400, | |
Accented = 0x0800, | |
Whitespace = 0x1000, | |
NewLine = 0x2000 | |
} | |
#endregion | |
#region Main Class | |
/// <summary> | |
/// RandomEx class that uses the Cryptographically Secure RNG and provides some conversion | |
/// functionality for ease of use | |
/// </summary> | |
/// <remarks> | |
/// "The generation of random numbers is too important to be left to chance." --Robert R. Coveyou | |
/// </remarks> | |
public class RandomEx : IDisposable | |
{ | |
#region Constructor / Destructor | |
public RandomEx() | |
: this( DEFAULT_BUFFER_SIZE ) | |
{ | |
} | |
public RandomEx( int nBufferSize ) | |
{ | |
this.RNG = new RNGCryptoServiceProvider(); | |
m_RandData = new byte[nBufferSize]; | |
GetBytes( m_RandData ); | |
} | |
~RandomEx() | |
{ | |
(this as IDisposable).Dispose(); | |
} | |
#endregion | |
#region Properties | |
public bool Bool { get { return GetBool(); } } | |
public byte Byte { get { return GetByte(); } } | |
public char Char { get { return GetChar(); } } | |
public DateTime DateTime { get { return GetDateTime(); } } | |
public decimal Decimal { get { return GetDecimal(); } } | |
public double Double { get { return GetDouble(); } } | |
public float Float { get { return GetFloat(); } } | |
public Guid Guid { get { return GetGuid(); } } | |
public int Int { get { return GetInt(); } } | |
public long Long { get { return GetLong(); } } | |
public sbyte SByte { get { return GetSByte(); } } | |
public short Short { get { return GetShort(); } } | |
public string String { get { return GetString(); } } | |
public TimeSpan TimeSpan { get { return GetTime(); } } | |
public uint UInt { get { return GetUInt(); } } | |
public ulong ULong { get { return GetULong(); } } | |
public ushort UShort { get { return GetUShort(); } } | |
#endregion | |
#region Basic "Get" Functions | |
public bool GetBool() { return ((GetByte() & 0x01) == 0x01); } | |
public byte GetByte() { return m_RandData[EnsureBytes( sizeof( byte ) )]; } | |
public void GetBytes( byte[] data ) { RNG.GetBytes( data ); } | |
public char GetChar() { return GetChar( DEFAULT_CHAR_SETS ); } | |
public double GetDouble() { return BitConverter.ToDouble( m_RandData, EnsureBytes( sizeof( double ) ) ); } | |
public float GetFloat() { return BitConverter.ToSingle( m_RandData, EnsureBytes( sizeof( float ) ) ); } | |
#if DEBUG | |
public Guid GetGuid() { return new Guid( Int, Short, Short, Byte, Byte, Byte, Byte, Byte, Byte, Byte, Byte ); } | |
#else | |
public Guid GetGuid() { return Guid.NewGuid(); } | |
#endif | |
public int GetInt() { return BitConverter.ToInt32( m_RandData, EnsureBytes( sizeof( int ) ) ); } | |
public long GetLong() { return BitConverter.ToInt64( m_RandData, EnsureBytes( sizeof( long ) ) ); } | |
public sbyte GetSByte() { unchecked { return (sbyte)GetByte(); } } | |
public short GetShort() { return BitConverter.ToInt16( m_RandData, EnsureBytes( sizeof( short ) ) ); } | |
public uint GetUInt() { return BitConverter.ToUInt32( m_RandData, EnsureBytes( sizeof( uint ) ) ); } | |
public ulong GetULong() { return BitConverter.ToUInt64( m_RandData, EnsureBytes( sizeof( ulong ) ) ); } | |
public ushort GetUShort() { return BitConverter.ToUInt16( m_RandData, EnsureBytes( sizeof( ushort ) ) ); } | |
#endregion | |
#region Percentage Functions | |
public double GetPercentage() | |
{ | |
return (double)((double)GetULong() / (double)UInt64.MaxValue); | |
} | |
public decimal GetPercentageDecimal() | |
{ | |
return decimal.Divide( GetDecimal( false, 0 ), Decimal.MaxValue ); | |
} | |
/// <summary>Performs a "Success" check boolean based on the probability for success.</summary> | |
/// <param name="nChanceForSuccess">Percent Change of Success (must be between 0 and 1.0)</param> | |
/// <returns>Boolean indicating if successful or not</returns> | |
public bool SuccessCheck( double nChanceForSuccess ) | |
{ | |
Debug.Assert( nChanceForSuccess.IsBetween( 0, 1.0, true ) ); | |
return (GetPercentage() <= nChanceForSuccess); | |
} | |
public bool SuccessCheck( decimal nChanceForSuccess ) | |
{ | |
Debug.Assert( nChanceForSuccess.IsBetween( 0.0m, 1.0m, true ) ); | |
return (GetPercentageDecimal() <= nChanceForSuccess); | |
} | |
#endregion | |
#region Pick Functions | |
public T Pick<T>( params T[] items ) | |
{ | |
return Pick<T>( items.AsEnumerable() ); | |
} | |
public T Pick<T>( IEnumerable<T> items ) | |
{ | |
if ( items == null ) | |
{ | |
throw new ArgumentNullException( "items" ); | |
} | |
int count = items.Count(); | |
if ( count == 0 ) | |
{ | |
throw new ArgumentException( "Enumerator had no items", "items" ); | |
} | |
return items.ElementAt( GetInt( 0, count - 1 ) ); | |
} | |
#endregion | |
#region Advanced "Get" Functions | |
#region Get Char Functions | |
public char GetChar( string sCharSet ) { return sCharSet[GetInt( 0, sCharSet.Length - 1 )]; } | |
public char GetChar( string[] sCharSets ) { return GetChar( String.Join( "", sCharSets ) ); } | |
public char GetChar( RandomCharSets chars ) { return GetChar( chars.GetCharSets() ); } | |
#endregion | |
#region Get Decimal Functions | |
public decimal GetDecimal() { return GetDecimal( GetBool(), 0xff ); } | |
public decimal GetDecimal( byte scale ) { return GetDecimal( GetBool(), scale ); } | |
public decimal GetDecimal( bool bNeg ) { return GetDecimal( bNeg, 0xff ); } | |
public decimal GetDecimal( bool bNeg, byte scale ) | |
{ | |
const byte MAX_SCALE = 28; | |
if ( scale > MAX_SCALE ) | |
{ | |
scale = (byte)(GetPercentage() * MAX_SCALE); | |
} | |
return new decimal( GetInt(), GetInt(), GetInt(), bNeg, scale ); | |
} | |
#endregion | |
#region "Ranged" Get (between a min and max) | |
public decimal GetDecimal( decimal min, decimal max ) | |
{ | |
if ( min <= max ) | |
{ | |
return ((max - min) * (decimal)GetPercentage()) + min; | |
} | |
else | |
{ | |
return GetDecimal( max, min ); | |
} | |
} | |
public double GetDouble( double min, double max ) | |
{ | |
if ( min <= max ) | |
{ | |
return ((max - min) * GetPercentage()) + min; | |
} | |
else | |
{ | |
return GetDouble( max, min ); | |
} | |
} | |
public float GetFloat( float min, float max ) | |
{ | |
if ( min <= max ) | |
{ | |
return (float)((double)(max - min) * GetPercentage() + (double)min); | |
} | |
else | |
{ | |
return GetFloat( max, min ); | |
} | |
} | |
public int GetInt( int min, int max ) | |
{ | |
if ( min <= max ) | |
{ | |
// + 1 So that the min and max range is INCLUSIVE | |
return (int)((double)((double)max - (double)min + 1.0) * GetPercentage()) + min; | |
} | |
else | |
{ | |
return GetInt( max, min ); | |
} | |
} | |
public long GetLong( long min, long max ) | |
{ | |
if ( min <= max ) | |
{ | |
// + 1 So that the min and max range is INCLUSIVE | |
return (long)((double)(double)(max - (double)min + 1.0) * GetPercentage()) + min; | |
} | |
else | |
{ | |
return GetLong( max, min ); | |
} | |
} | |
#endregion | |
#region "Max" Get Functions | |
public decimal GetDecimal( decimal max ) { return GetDecimal( 0, max ); } | |
public double GetFloat( float max ) { return GetFloat( 0, max ); } | |
public double GetDouble( double max ) { return GetDouble( 0, max ); } | |
public long GetLong( long max ) { return GetLong( 0, max ); } | |
public int GetInt( int max ) { return GetInt( 0, max ); } | |
#endregion | |
#region Enum Get Functions | |
public TEnum GetEnum<TEnum>() where TEnum : struct { return (TEnum)GetEnum( typeof( TEnum ) ); } | |
public object GetEnum( Type t ) { Debug.Assert( t.IsEnum ); return GetElement( Enum.GetValues( t ) ); } | |
public TEnum GetEnum<TEnum>( Func<TEnum, bool> fnSelector ) where TEnum : struct | |
{ | |
TEnum val; | |
do | |
{ | |
val = GetEnum<TEnum>(); | |
} | |
while ( !fnSelector( val ) ); | |
return val; | |
} | |
#endregion | |
#region DateTime / TimeSpan Functions | |
public DateTime GetDateTime( DateTime min, DateTime max ) | |
{ | |
return DateTime.FromBinary( GetLong( min.ToBinary(), max.ToBinary() ) ); | |
} | |
public DateTime GetDateTime( DateTime start, TimeSpan span ) | |
{ | |
DateTime end = start + span; | |
if ( span.Ticks >= 0 ) | |
{ | |
return GetDateTime( start, end ); | |
} | |
else | |
{ | |
return GetDateTime( end, start ); | |
} | |
} | |
public DateTime GetDateTime( TimeSpan span, bool bPlusAndMinus = false ) | |
{ | |
if ( bPlusAndMinus ) | |
{ | |
return GetDateTime( DateTime.Now - span, DateTime.Now + span ); | |
} | |
else | |
{ | |
return GetDateTime( DateTime.Today, span ); | |
} | |
} | |
public DateTime GetDateTime( int nDaysAhead ) | |
{ | |
DateTime start = DateTime.Now; | |
return GetDateTime( start, start.AddDays( nDaysAhead ) ); | |
} | |
public DateTime GetDateTime() | |
{ | |
return GetDateTime( GetInt( 1, 100 ) ); | |
} | |
public DateTime GetDateTimeInYear( int year ) | |
{ | |
DateTime start = new DateTime( year, 1, 1 ); | |
return GetDateTime( start, start.AddYears( 1 ) ); | |
} | |
public DateTime GetDateTimeToday() | |
{ | |
return DateTime.Today + GetTime(); | |
} | |
public TimeSpan GetTime() | |
{ | |
const long ONE_DAY_TICKS = 864000000000; | |
return new TimeSpan( GetLong( 0, ONE_DAY_TICKS ) ); | |
} | |
public TimeSpan GetTimeSpan( TimeSpan min, TimeSpan max ) | |
{ | |
return new TimeSpan( GetLong( min.Ticks, max.Ticks ) ); | |
} | |
#endregion | |
#endregion | |
#region Object Functions | |
public object Get( Type t ) | |
{ | |
switch ( Type.GetTypeCode( t ) ) | |
{ | |
case TypeCode.Boolean: return GetBool(); | |
case TypeCode.Char: return GetChar(); | |
case TypeCode.SByte: return GetSByte(); | |
case TypeCode.Byte: return GetByte(); | |
case TypeCode.Int16: return GetShort(); | |
case TypeCode.UInt16: return GetUShort(); | |
case TypeCode.Int32: return GetInt(); | |
case TypeCode.UInt32: return GetUInt(); | |
case TypeCode.Int64: return GetLong(); | |
case TypeCode.UInt64: return GetULong(); | |
case TypeCode.Single: return GetFloat(); | |
case TypeCode.Double: return GetDouble(); | |
case TypeCode.Decimal: return GetDecimal(); | |
case TypeCode.DateTime: return GetDateTime(); | |
case TypeCode.String: return GetString(); | |
case TypeCode.Empty: return null; | |
case TypeCode.DBNull: return null; | |
case TypeCode.Object: | |
default: | |
// Do nothing so it can be handled the hard way | |
break; | |
} | |
// Check these types without TypeCode values | |
if ( t == typeof( TimeSpan ) ) return GetTime(); | |
if ( t == typeof( Guid ) ) return GetGuid(); | |
if ( t.IsEnum ) return GetEnum( t ); | |
// If all else fails, see if it can be ASSIGNED from a type this function can create, | |
// and return that instead | |
var assignable = ASSIGNABLES.Where( w => t.IsAssignableFrom( w ) ); | |
if ( assignable.Any() ) | |
{ | |
return Get( assignable.First() ); | |
} | |
Debug.WriteLine( String.Format( "Cannot \"Get\" a randomized value for Type: {0}", t.Name ) ); | |
return null; | |
} | |
public Array Get( Type t, int count ) | |
{ | |
return System.Linq.Enumerable.Range( 0, count ).Select( s => Get( t ) ).ToArray(); | |
} | |
public Array Get( Type t, int countMin, int countMax ) | |
{ | |
return Get( t, GetInt( countMin, countMax ) ); | |
} | |
public object[] Get( params Type[] types ) | |
{ | |
return Get( types.AsEnumerable() ).ToArray(); | |
} | |
public IEnumerable<object> Get( IEnumerable<Type> types ) | |
{ | |
return types.Select( t => Get( t ) ); | |
} | |
public T Get<T>() | |
{ | |
return (T)Get( typeof( T ) ); | |
} | |
public IEnumerable<T> Get<T>( int count ) | |
{ | |
return Enumerable.Range( 0, count ).Select( s => Get<T>() ); | |
} | |
public IEnumerable<T> Get<T>( int countMin, int countMax ) | |
{ | |
return Get<T>( GetInt( countMin, countMax ) ); | |
} | |
public object GetElement( Array a ) | |
{ | |
return a.GetValue( Enumerable.Range( 0, a.Rank ) | |
.Select( i => GetInt( a.GetLowerBound( i ), a.GetUpperBound( i ) ) ) | |
.ToArray() ); | |
} | |
public void SetElements( Type t, Array a ) | |
{ | |
int[] indices = new int[a.Rank]; | |
_SetElements( t, a, indices, 0 ); | |
} | |
private void _SetElements( Type t, Array a, int[] indices, int rank ) | |
{ | |
Action action = null; | |
if ( rank == (a.Rank - 1) ) | |
{ | |
// If this is the last rank, inside of the loop, Actually set the value | |
action = () => a.SetValue( Get( t ), indices ); | |
} | |
else | |
{ | |
// If this isn't the last rank, inside of the loop, Move on to the next rank | |
action = () => _SetElements( t, a, indices, rank + 1 ); | |
} | |
// Loop through all values of this rank | |
int lower = a.GetLowerBound( rank ); | |
int upper = a.GetUpperBound( rank ); | |
for ( int i = lower ; i <= upper ; ++i ) | |
{ | |
// Set the index in this rank | |
indices[rank] = i; | |
// Perform the "action" | |
action(); | |
} | |
} | |
private readonly Type[] ASSIGNABLES = new Type[] | |
{ | |
typeof( Int32 ), typeof( UInt32 ), | |
typeof( Int64 ), typeof( UInt64 ), | |
typeof( Int16 ), typeof( UInt16 ), | |
typeof( Double ), typeof( Single ), | |
typeof( DateTime ), typeof( TimeSpan ), | |
typeof( String ), typeof( Guid ), | |
typeof( Byte ), typeof( SByte ), | |
typeof( Char ), typeof( Boolean ), | |
typeof( Decimal ) | |
}; | |
#endregion | |
#region Reflection / Object Configuration | |
public void Randomize<T>( object target, bool bRecursive = true ) | |
{ | |
Randomize( typeof( T ), target, bRecursive ); | |
} | |
public void Randomize( Type t, object target, bool bRecursive = true ) | |
{ | |
var props = t.GetProperties(); | |
if ( !props.Any() ) | |
{ | |
throw new ArgumentException( "No Properties", "target" ); | |
} | |
foreach ( var p in props ) | |
{ | |
try | |
{ | |
if ( p.CanWrite ) | |
{ | |
object value = Get( p.PropertyType ); | |
if ( value != null ) | |
{ | |
p.SetValue( target, value, null ); | |
} | |
else | |
{ | |
if ( bRecursive && p.CanRead ) | |
{ | |
value = p.GetValue( target, null ); | |
if ( value != null ) | |
{ | |
if ( p.PropertyType.IsArray ) | |
{ | |
SetElements( p.PropertyType.GetElementType(), (value as Array) ); | |
} | |
else | |
{ | |
Randomize( p.PropertyType, value, bRecursive ); | |
} | |
} | |
} | |
} | |
} | |
} | |
catch ( Exception e ) | |
{ | |
Debug.WriteLine( "Caught Exception while Randomizing: " + e.ToString() ); | |
} | |
} | |
} | |
#endregion | |
#region Conversion Operators | |
public static implicit operator bool( RandomEx rand ) { return rand.GetBool(); } | |
public static implicit operator byte( RandomEx rand ) { return rand.GetByte(); } | |
public static implicit operator float( RandomEx rand ) { return rand.GetFloat(); } | |
public static implicit operator uint( RandomEx rand ) { return rand.GetUInt(); } | |
public static implicit operator short( RandomEx rand ) { return rand.GetShort(); } | |
public static implicit operator string( RandomEx rand ) { return rand.GetString(); } | |
public static implicit operator long( RandomEx rand ) { return rand.GetLong(); } | |
public static implicit operator char( RandomEx rand ) { return rand.GetChar(); } | |
public static implicit operator double( RandomEx rand ) { return rand.GetDouble(); } | |
public static implicit operator DateTime( RandomEx rand ) { return rand.GetDateTime(); } | |
public static implicit operator TimeSpan( RandomEx rand ) { return rand.GetTime(); } | |
public static implicit operator ulong( RandomEx rand ) { return rand.GetULong(); } | |
public static implicit operator Guid( RandomEx rand ) { return rand.GetGuid(); } | |
public static implicit operator sbyte( RandomEx rand ) { return rand.GetSByte(); } | |
public static implicit operator decimal( RandomEx rand ) { return rand.GetDecimal(); } | |
public static implicit operator ushort( RandomEx rand ) { return rand.GetUShort(); } | |
public static implicit operator int( RandomEx rand ) { return rand.GetInt(); } | |
#endregion | |
#region String Functions | |
public string GetString( int min, int max, string sCharSet ) | |
{ | |
const string SINGLE_CHAR_LINE = "\n"; | |
string result = String.Empty; | |
int length = GetInt( min, max ); | |
bool bFixNewLine = false; | |
// If NewLine is more than one character, convert it to a single char to use | |
if ( Environment.NewLine != SINGLE_CHAR_LINE ) | |
{ | |
bFixNewLine = (sCharSet != (sCharSet = sCharSet.Replace( Environment.NewLine, SINGLE_CHAR_LINE ))); | |
} | |
do | |
{ | |
result += sCharSet[GetInt( 0, sCharSet.Length - 1 )]; | |
} | |
while ( result.Length < length ); | |
// If the NewLine substitution was done before, expand it back to the multi character version | |
if ( bFixNewLine ) | |
{ | |
result = result.Replace( SINGLE_CHAR_LINE, Environment.NewLine ); | |
} | |
return result; | |
} | |
public string GetString( int min, int max, string[] sCharSets ) { return GetString( min, max, String.Join( "", sCharSets ) ); } | |
public string GetString( int min, int max, RandomCharSets chars ) { return GetString( min, max, chars.GetCharSets() ); } | |
public string GetString( int min, int max ) { return GetString( min, max, DEFAULT_CHAR_SETS ); } | |
public string GetString( int max, string sCharSet ) { return GetString( 1, max, sCharSet ); } | |
public string GetString( int max, string[] sCharSets ) { return GetString( 1, max, sCharSets ); } | |
public string GetString( int max, RandomCharSets chars ) { return GetString( 1, max, chars ); } | |
public string GetString( int max ) { return GetString( 1, max ); } | |
public string GetString() { return GetString( 1, DEFAULT_STRING_MAX ); } | |
#endregion | |
#region Extended String Functions | |
public string GetExtString( int max ) | |
{ | |
return GetExtString( 1, max ); | |
} | |
public string GetExtString( int min, int max ) | |
{ | |
RandomCharSets cs; | |
do | |
{ | |
cs = (RandomCharSets)(GetUShort() & (ushort)EXT_CHAR_SETS); | |
} | |
// Repeat until a useful value is generated | |
while ( cs == RandomCharSets.None ); | |
// Get the string | |
return GetString( min, max, cs ); | |
} | |
#endregion | |
#region Internals | |
private RNGCryptoServiceProvider RNG { get; set; } | |
/// <summary> | |
/// Ensures there are at least "count" bytes of random data available and indicates where in | |
/// the buffer to find them | |
/// </summary> | |
/// <param name="count">The number of random bytes needed</param> | |
/// <returns>The Index into m_RandData where the random bytes can be found</returns> | |
private int EnsureBytes( int count ) | |
{ | |
// See if there's enough data left in the buffer to fulfill this request | |
if ( (m_nUsedCount + count) <= m_RandData.Length ) | |
{ | |
// There is so mark it as used | |
int index = m_nUsedCount; | |
m_nUsedCount += count; | |
return index; | |
} | |
else | |
{ | |
// See if they want more data than the buffer can hold | |
if ( count > m_RandData.Length ) | |
{ | |
// Grow the buffer by the size plus extra | |
m_RandData = new byte[(int)(count * 1.5)]; | |
} | |
// Get more data | |
GetBytes( m_RandData ); | |
m_nUsedCount = count; | |
return 0; | |
} | |
} | |
private int m_nUsedCount = 0; | |
private byte[] m_RandData; | |
#endregion | |
#region Constants | |
private const int DEFAULT_BUFFER_SIZE = 4096; | |
private const RandomCharSets DEFAULT_CHAR_SETS = (RandomCharSets.LowerCase | RandomCharSets.UpperCase | | |
RandomCharSets.Symbols | RandomCharSets.SymbolsExt | | |
RandomCharSets.Numbers); | |
private const int DEFAULT_STRING_MAX = 32; | |
private const RandomCharSets EXT_CHAR_SETS = (DEFAULT_CHAR_SETS | RandomCharSets.GreekUpper | RandomCharSets.GreekLower); | |
#endregion | |
#region IDisposable Members | |
void IDisposable.Dispose() | |
{ | |
if ( this.RNG != null ) | |
{ | |
this.RNG.Dispose(); | |
this.RNG = null; | |
} | |
} | |
#endregion | |
} | |
#endregion | |
#region Internal Helper Classes | |
internal static class CharSetExtensions | |
{ | |
#region Public Methods | |
public static string GetChars( this RandomCharSets val ) | |
{ | |
const string UPPERALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
const string LOWERALPHA = "abcdefghijklmnopqrstuvwxyz"; | |
const string NUMERICS = "0123456789"; | |
const string SYMBOLS1 = "!@#$%^&*()"; | |
const string SYMBOLS2 = "-=~[]|\\?//,.<>:;'\"{}"; | |
const string EXTRAPUNC= "¡¦©«®°¶·¿―‗’‛”„†‡…′″‴‹›‼‽‾⁃⁄"; | |
const string CURRENCY = "$¢£¤¥฿₠₡₢₣₤₥₦₧₨₩₫€₪"; | |
const string GREEKCAPITAL = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ"; | |
const string GREEKLOWER = "αβγδεζηθικλμνξοπρςστυφχψω"; | |
const string DINGBATS = "☺☻☼♀♂♠♣♥♦♪♫✶"; | |
const string CIRCNUMBERS = "❶❷❸❹❺❻❼❽❾❿"; | |
const string ACCENTED = "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ"; | |
const string SPACE = " "; | |
switch ( val ) | |
{ | |
case RandomCharSets.UpperCase: return UPPERALPHA; | |
case RandomCharSets.LowerCase: return LOWERALPHA; | |
case RandomCharSets.Numbers: return NUMERICS; | |
case RandomCharSets.Symbols: return SYMBOLS1; | |
case RandomCharSets.SymbolsExt: return SYMBOLS2; | |
case RandomCharSets.ExtraPunc: return EXTRAPUNC; | |
case RandomCharSets.Currency: return CURRENCY; | |
case RandomCharSets.GreekUpper: return GREEKCAPITAL; | |
case RandomCharSets.GreekLower: return GREEKLOWER; | |
case RandomCharSets.Dingbats: return DINGBATS; | |
case RandomCharSets.CircleNums: return CIRCNUMBERS; | |
case RandomCharSets.Accented: return ACCENTED; | |
case RandomCharSets.Whitespace: return SPACE; | |
case RandomCharSets.NewLine: return Environment.NewLine; | |
default: return String.Empty; | |
} | |
} | |
public static string[] GetCharSets( this RandomCharSets val ) | |
{ | |
return Enum.GetValues( typeof( RandomCharSets ) ) | |
.OfType<RandomCharSets>() | |
.Where( w => val.HasFlag( w ) ) | |
.Select( s => s.GetChars() ) | |
.ToArray(); | |
} | |
#endregion Public Methods | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment