1:
37:
38:
39: package ;
40:
41: import ;
42:
43:
46: public abstract class BasePRNG
47: implements IRandom
48: {
49:
50: protected String name;
51:
52:
53: protected boolean initialised;
54:
55:
56: protected byte[] buffer;
57:
58:
59: protected int ndx;
60:
61:
66: protected BasePRNG(String name)
67: {
68: super();
69:
70: this.name = name;
71: initialised = false;
72: buffer = new byte[0];
73: }
74:
75: public String name()
76: {
77: return name;
78: }
79:
80: public void init(Map attributes)
81: {
82: this.setup(attributes);
83:
84: ndx = 0;
85: initialised = true;
86: }
87:
88: public byte nextByte() throws IllegalStateException, LimitReachedException
89: {
90: if (! initialised)
91: throw new IllegalStateException();
92:
93: return nextByteInternal();
94: }
95:
96: public void nextBytes(byte[] out) throws IllegalStateException,
97: LimitReachedException
98: {
99: nextBytes(out, 0, out.length);
100: }
101:
102: public void nextBytes(byte[] out, int offset, int length)
103: throws IllegalStateException, LimitReachedException
104: {
105: if (! initialised)
106: throw new IllegalStateException("not initialized");
107:
108: if (length == 0)
109: return;
110:
111: if (offset < 0 || length < 0 || offset + length > out.length)
112: throw new ArrayIndexOutOfBoundsException("offset=" + offset + " length="
113: + length + " limit="
114: + out.length);
115: if (ndx >= buffer.length)
116: {
117: fillBlock();
118: ndx = 0;
119: }
120: int count = 0;
121: while (count < length)
122: {
123: int amount = Math.min(buffer.length - ndx, length - count);
124: System.arraycopy(buffer, ndx, out, offset + count, amount);
125: count += amount;
126: ndx += amount;
127: if (ndx >= buffer.length)
128: {
129: fillBlock();
130: ndx = 0;
131: }
132: }
133: }
134:
135: public void addRandomByte(byte b)
136: {
137: throw new UnsupportedOperationException("random state is non-modifiable");
138: }
139:
140: public void addRandomBytes(byte[] buffer)
141: {
142: addRandomBytes(buffer, 0, buffer.length);
143: }
144:
145: public void addRandomBytes(byte[] buffer, int offset, int length)
146: {
147: throw new UnsupportedOperationException("random state is non-modifiable");
148: }
149:
150: public boolean isInitialised()
151: {
152: return initialised;
153: }
154:
155: private byte nextByteInternal() throws LimitReachedException
156: {
157: if (ndx >= buffer.length)
158: {
159: this.fillBlock();
160: ndx = 0;
161: }
162:
163: return buffer[ndx++];
164: }
165:
166: public Object clone() throws CloneNotSupportedException
167: {
168: BasePRNG result = (BasePRNG) super.clone();
169: if (this.buffer != null)
170: result.buffer = (byte[]) this.buffer.clone();
171:
172: return result;
173: }
174:
175: public abstract void setup(Map attributes);
176:
177: public abstract void fillBlock() throws LimitReachedException;
178: }