001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010:
011: package org.mmbase.util;
012:
013: /**
014: * Class for holding a pool of random numbers.
015: * Calling {@link #stir} takes care of generating a new 'random' number.
016: * Calling {@link #value} returns the current random number.
017: *
018: * @author Rico Jansen
019: * @author Pierre van Rooden (javadocs)
020: * @version $Id: RandomPool.java,v 1.8 2005/10/05 10:44:00 michiel Exp $
021: */
022: public class RandomPool {
023:
024: /**
025: * Current random value.
026: * Initial to a value from MD5 64-bit pool of randomness.
027: * This values is maintained by {@link #stir}, and is
028: * the value that is actually returned by {@link #value}
029: * #see {@link #stir}
030: */
031: private static long ranPool = 0x67452301efcdab89L;
032:
033: /**
034: * Pool of magic numbers.
035: * The following 31 constants are the first 62 "magic" numbers
036: * from the MD5 algorithm, RFC1321, concatenated in pairs to
037: * form 64-bit Java long words. Any random 64-bit values would do,
038: * but these were selected from a public source for added user confidence.
039: * The stir algorithm itself has nothing to do with MD5.
040: */
041: // No need to do it everytime EJJ
042: private static long p[] = { 0xd76aa478e8c7b756L, // 1,2
043: 0x242070dbc1bdceeeL, // 3,4
044: 0xf57c0faf4787c62aL, // 5,6
045: 0xa8304613fd469501L, // 7,8
046: 0x698098d88b44f7afL, // 8,10
047: 0xffff5bb1895cd7beL, // 11,12
048: 0x6b901122fd987193L, // 13,14
049: 0xa679438e49b40821L, // 15,16
050: 0xf61e2562c040b340L, // 17,18
051: 0x265e5a51e9b6c7aaL, // 19,20
052: 0xd62f105d02441453L, // 21,22
053: 0xd8a1e681e7d3fbc8L, // 23,24
054: 0x21e1cde6c33707d6L, // 25,26
055: 0xf4d50d87455a14edL, // 27,28
056: 0xa9e3e905fcefa3f8L, // 29,30
057: 0x676f02d98d2a4c8aL, // 31,32
058: 0xfffa39428771f681L, // 33,34
059: 0x6d9d6122fde5380cL, // 35,36
060: 0xa4beea444bdecfa9L, // 37,38
061: 0xf6bb4b60bebfbc70L, // 39,40
062: 0x289b7ec6eaa127faL, // 41,42
063: 0xd4ef308504881d05L, // 43,44
064: 0xd9d4d039e6db99e5L, // 45,46
065: 0x1fa27cf8c4ac5665L, // 47,48
066: 0xf4292244432aff97L, // 49,50
067: 0xab9423a7fc93a039L, // 51,52
068: 0x655b59c38f0ccc92L, // 53,54
069: 0xffeff47d85845dd1L, // 55,56
070: 0x6fa87e4ffe2ce6e0L, // 57,58
071: 0xa30143144e0811a1L, // 59,60
072: 0xf7537e82bd3af235L // 61,62
073: };
074:
075: /**
076: * Create a pool.
077: * Use the current time (long milliseconds) as a source of randomness
078: */
079: public RandomPool() {
080: stir(System.currentTimeMillis());
081: }
082:
083: /**
084: * Create a pool.
085: * @param init the source of randomness
086: */
087: public RandomPool(long init) {
088: stir(init);
089: }
090:
091: /**
092: * Maintain a pool of randomness using a modified 64-bit
093: * congruential generator with multipliers dynamically
094: * selected from a set of pseudo-random values.
095: * @param x the source of randomness
096: */
097: public synchronized void stir(long x) {
098: int pIndex;
099:
100: pIndex = mod(ranPool, p.length);
101: ranPool = (ranPool + x) * p[pIndex];
102: pIndex = mod(ranPool, p.length);
103: ranPool = ranPool ^ p[pIndex];
104: }
105:
106: /**
107: * Returns the current random value.
108: */
109: public long value() {
110: return (ranPool);
111: }
112:
113: /**
114: * Stirs, then returns the (new) current random value.
115: * Use the current time (long milliseconds) as a source of randomness
116: * for stirring.
117: */
118: public long value_and_stir() {
119: stir(System.currentTimeMillis());
120: return (ranPool);
121: }
122:
123: /**
124: * Stirs, then returns the (new) current random value.
125: * @param mix the source of randomness for stirring
126: */
127: public long value_and_stir(long mix) {
128: stir(mix);
129: return (ranPool);
130: }
131:
132: /**
133: * Returns the positive modulus of the arguments.
134: * @param x the argument to modulate
135: * @param y the argument to modulate with
136: * @return the positive modulus of x modulus y.
137: */
138: private int mod(long x, long y) {
139: if (x < 0)
140: x = -x;
141: if (y < 0)
142: y = -y;
143: return (int) (x % y);
144: }
145: }
|