source: trunk/eraser6/Eraser.Manager/PRNG.cs @ 1359

Revision 1359, 6.5 KB checked in by lowjoel, 5 years ago (diff)

Set svn:eol-style to native

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By: Kasra Nassiri <cjax@users.sourceforge.net>
6 * Modified By:
7 *
8 * This file is part of Eraser.
9 *
10 * Eraser is free software: you can redistribute it and/or modify it under the
11 * terms of the GNU General Public License as published by the Free Software
12 * Foundation, either version 3 of the License, or (at your option) any later
13 * version.
14 *
15 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 *
19 * A copy of the GNU General Public License can be found at
20 * <http://www.gnu.org/licenses/>.
21 */
22
23using System;
24using System.Collections.Generic;
25using System.Text;
26
27using System.Threading;
28using System.Security.Cryptography;
29using System.Runtime.InteropServices;
30using System.Diagnostics;
31using System.Reflection;
32using System.IO;
33using Microsoft.Win32.SafeHandles;
34using Eraser.Util;
35
36namespace Eraser.Manager
37{
38    /// <summary>
39    /// An interface class for all pseudorandom number generators used for the
40    /// random data erase passes.
41    /// </summary>
42    public abstract class Prng
43    {
44        public override string ToString()
45        {
46            return Name;
47        }
48
49        /// <summary>
50        /// The name of this erase pass, used for display in the UI
51        /// </summary>
52        public abstract string Name
53        {
54            get;
55        }
56
57        /// <summary>
58        /// The GUID for this PRNG.
59        /// </summary>
60        public abstract Guid Guid
61        {
62            get;
63        }
64
65        /// <summary>
66        /// Reseeds the PRNG. This can be called by inherited classes, but its most
67        /// important function is to provide new seeds regularly. The PRNGManager
68        /// will call this function once in a whle to maintain the quality of
69        /// generated numbers.
70        /// </summary>
71        /// <param name="seed">An arbitrary length of information that will be
72        /// used to reseed the PRNG</param>
73        protected internal abstract void Reseed(byte[] seed);
74
75        #region Random members
76        /// <summary>
77        /// Returns a nonnegative random number less than the specified maximum.
78        /// </summary>
79        /// <param name="maxValue">The exclusive upper bound of the random number
80        /// to be generated. maxValue must be greater than or equal to zero.</param>
81        /// <returns>A 32-bit signed integer greater than or equal to zero, and
82        /// less than maxValue; that is, the range of return values ordinarily
83        /// includes zero but not maxValue. However, if maxValue equals zero,
84        /// maxValue is returned.</returns>
85        public int Next(int maxValue)
86        {
87            if (maxValue == 0)
88                return 0;
89            return Next() % maxValue;
90        }
91
92        /// <summary>
93        /// Returns a random number within a specified range.
94        /// </summary>
95        /// <param name="minValue">The inclusive lower bound of the random number
96        /// returned.</param>
97        /// <param name="maxValue">The exclusive upper bound of the random number
98        /// returned. maxValue must be greater than or equal to minValue.</param>
99        /// <returns>A 32-bit signed integer greater than or equal to minValue and
100        /// less than maxValue; that is, the range of return values includes minValue
101        /// but not maxValue. If minValue equals maxValue, minValue is returned.</returns>
102        public int Next(int minValue, int maxValue)
103        {
104            if (minValue > maxValue)
105                throw new ArgumentOutOfRangeException("minValue", minValue,
106                    S._("minValue is greater than maxValue"));
107            else if (minValue == maxValue)
108                return minValue;
109            return (Next() % (maxValue - minValue)) + minValue;
110        }
111
112        /// <summary>
113        /// Returns a nonnegative random number.
114        /// </summary>
115        /// <returns>A 32-bit signed integer greater than or equal to zero and less
116        /// than System.Int32.MaxValue.</returns>
117        public unsafe int Next()
118        {
119            //Declare a return variable
120            int result;
121            int* fResult = &result;
122
123            //Get the random-valued bytes to fill the int.
124            byte[] rand = new byte[sizeof(int)];
125            NextBytes(rand);
126
127            //Copy the random buffer into the int.
128            fixed (byte* fRand = rand)
129            {
130                byte* pResult = (byte*)fResult;
131                byte* pRand = fRand;
132                for (int i = 0; i != sizeof(int); ++i)
133                    *pResult++ = *pRand++;
134            }
135
136            return Math.Abs(result);
137        }
138
139        /// <summary>
140        /// Fills the elements of a specified array of bytes with random numbers.
141        /// </summary>
142        /// <param name="buffer">An array of bytes to contain random numbers.</param>
143        public abstract void NextBytes(byte[] buffer);
144        #endregion
145    }
146
147    /// <summary>
148    /// Class managing all the PRNG algorithms.
149    /// </summary>
150    public class PrngManager
151    {
152        /// <summary>
153        /// Constructor.
154        /// </summary>
155        public PrngManager()
156        {
157        }
158
159        /// <summary>
160        /// Retrieves all currently registered erasure methods.
161        /// </summary>
162        /// <returns>A mutable list, with an instance of each PRNG.</returns>
163        public static Dictionary<Guid, Prng> Items
164        {
165            get
166            {
167                lock (ManagerLibrary.Instance.PRNGManager.prngs)
168                    return ManagerLibrary.Instance.PRNGManager.prngs;
169            }
170        }
171
172        /// <summary>
173        /// Retrieves the instance of the PRNG with the given GUID.
174        /// </summary>
175        /// <param name="value">The GUID of the PRNG.</param>
176        /// <returns>The PRNG instance.</returns>
177        public static Prng GetInstance(Guid value)
178        {
179            lock (ManagerLibrary.Instance.PRNGManager.prngs)
180            {
181                if (!ManagerLibrary.Instance.PRNGManager.prngs.ContainsKey(value))
182                    throw new PrngNotFoundException(value);
183                return ManagerLibrary.Instance.PRNGManager.prngs[value];
184            }
185        }
186
187        /// <summary>
188        /// Allows plug-ins to register PRNGs with the main program. Thread-safe.
189        /// </summary>
190        /// <param name="method"></param>
191        public static void Register(Prng prng)
192        {
193            lock (ManagerLibrary.Instance.PRNGManager.prngs)
194                ManagerLibrary.Instance.PRNGManager.prngs.Add(prng.Guid, prng);
195        }
196
197        /// <summary>
198        /// Allows the EntropyThread to get entropy to the PRNG functions as seeds.
199        /// </summary>
200        /// <param name="entropy">An array of bytes, being entropy for the PRNG.</param>
201        internal void AddEntropy(byte[] entropy)
202        {
203            lock (ManagerLibrary.Instance.PRNGManager.prngs)
204                foreach (Prng prng in prngs.Values)
205                    prng.Reseed(entropy);
206        }
207
208        /// <summary>
209        /// Gets entropy from the EntropyThread.
210        /// </summary>
211        /// <returns>A buffer of arbitrary length containing random information.</returns>
212        public static byte[] GetEntropy()
213        {
214            return ManagerLibrary.Instance.EntropySourceManager.Poller.GetPool();
215        }
216
217        /// <summary>
218        /// The list of currently registered erasure methods.
219        /// </summary>
220        private Dictionary<Guid, Prng> prngs = new Dictionary<Guid, Prng>();
221    }
222}
Note: See TracBrowser for help on using the repository browser.