[
https://issues.apache.org/jira/browse/MATH-710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Eldar Agalarov updated MATH-710:
--------------------------------
Description:
Dear developers, please add to Common Math library support for ISAAC random
number generator. This is a free and open-source PRNG
(http://burtleburtle.net/bob/rand/isaacafa.html).
Algorithm's rewrited (with some improvements) Java code from original C version
is attached.
was:
Dear developers, please add to Common Math library support for ISAAC random
number generator. This is a free and open-source PRNG
(http://burtleburtle.net/bob/rand/isaacafa.html).
Algorithm's rewrited (with some improvements) Java code from original C version:
import java.io.Serializable;
public final class ISAACRandom extends AbstractRandom implements Serializable,
Cloneable {
private static final long serialVersionUID = 7288197941165002400L;
private static final int SIZE_L = 8; /* log of size of rsl[]
and mem[] */
private static final int SIZE = 1 << SIZE_L; /* size of rsl[] and
mem[] */
private static final int H_SIZE = SIZE >> 1; /* half-size of rsl[]
and mem[] */
private static final int MASK = SIZE - 1 << 2; /* for pseudorandom
lookup */
private static final int GLD_RATIO = 0x9e3779b9; /* the golden ratio */
private static final long SEED_MASK = 0xffffffffL;
private int[] rsl; /* the results given to
the user */
private int[] mem; /* the internal state */
private int[] arr;
private int count; /* count through the
results in rsl[] */
private int a; /* accumulator */
private int b; /* the last result */
private int c; /* counter, guarantees
cycle is at least 2^^40 */
private transient int x;
private transient int i;
private transient int j;
public ISAACRandom() {
this(System.currentTimeMillis());
}
public ISAACRandom(long seed) {
allocArrays();
setSeed(seed);
}
public ISAACRandom(int[] seed) {
allocArrays();
setSeed(seed);
}
private void allocArrays() {
rsl = new int[SIZE];
mem = new int[SIZE];
arr = new int[8];
}
@Override
public void setSeed(int seed) {
setSeed(new int[]{seed});
}
@Override
public void setSeed(long seed) {
setSeed(new int[]{(int) (seed >>> 32), (int) (seed & SEED_MASK)});
}
@Override
public void setSeed(int[] seed) {
int seedLen = seed.length, rslLen = rsl.length;
System.arraycopy(seed, 0, rsl, 0, Math.min(seedLen, rslLen));
if (seedLen < rslLen) {
for (i = seedLen; i < rslLen; i++) {
long k = rsl[i - seedLen];
rsl[i] = (int) (0x6c078965L * (k ^ k >> 30) + i & SEED_MASK);
}
}
initState();
isaac();
count = SIZE - 1;
}
@Override
protected int next(int bits) {
if (count < 0) {
isaac();
count = SIZE - 1;
}
return rsl[count--] >>> 32 - bits;
}
private void isaac() {
i = 0; j = H_SIZE; b += ++c;
while (i < H_SIZE) isaac2();
j = 0;
while (j < H_SIZE) isaac2();
}
private void isaac2() {
x = mem[i]; a ^= a << 13; a += mem[j++]; isaac3();
x = mem[i]; a ^= a >>> 6; a += mem[j++]; isaac3();
x = mem[i]; a ^= a << 2; a += mem[j++]; isaac3();
x = mem[i]; a ^= a >>> 16; a += mem[j++]; isaac3();
}
private void isaac3() {
mem[i] = mem[(x & MASK) >> 2] + a + b;
b = mem[(mem[i] >> SIZE_L & MASK) >> 2] + x;
rsl[i++] = b;
}
private void initState() {
a = b = c = 0;
arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = arr[5] = arr[6] = arr[7] =
GLD_RATIO;
for (i = 0; i < 4; i++) shuffle();
for (i = 0; i < SIZE; i++) mem[i] = rsl[i] = 0;
for (i = 0; i < SIZE; i += 8) {
arr[0] += rsl[i]; arr[1] += rsl[i + 1]; arr[2] += rsl[i + 2];
arr[3] += rsl[i + 3]; arr[4] += rsl[i + 4]; arr[5] += rsl[i + 5];
arr[6] += rsl[i + 6]; arr[7] += rsl[i + 7];
shuffle(); setState();
}
for (i = 0; i < SIZE; i += 8) {
arr[0] += mem[i]; arr[1] += mem[i + 1]; arr[2] += mem[i + 2];
arr[3] += mem[i + 3]; arr[4] += mem[i + 4]; arr[5] += mem[i + 5];
arr[6] += mem[i + 6]; arr[7] += mem[i + 7];
shuffle(); setState();
}
}
private void shuffle() {
arr[0] ^= arr[1] << 11; arr[3] += arr[0]; arr[1] += arr[2];
arr[1] ^= arr[2] >>> 2; arr[4] += arr[1]; arr[2] += arr[3];
arr[2] ^= arr[3] << 8; arr[5] += arr[2]; arr[3] += arr[4];
arr[3] ^= arr[4] >>> 16; arr[6] += arr[3]; arr[4] += arr[5];
arr[4] ^= arr[5] << 10; arr[7] += arr[4]; arr[5] += arr[6];
arr[5] ^= arr[6] >>> 4; arr[0] += arr[5]; arr[6] += arr[7];
arr[6] ^= arr[7] << 8; arr[1] += arr[6]; arr[7] += arr[0];
arr[7] ^= arr[0] >>> 9; arr[2] += arr[7]; arr[0] += arr[1];
}
private void setState() {
mem[i] = arr[0]; mem[i + 1] = arr[1]; mem[i + 2] = arr[2];
mem[i + 3] = arr[3]; mem[i + 4] = arr[4]; mem[i + 5] = arr[5];
mem[i + 6] = arr[6]; mem[i + 7] = arr[7];
}
@Override
public ISAACRandom clone() {
try {
ISAACRandom cloned = (ISAACRandom) super.clone();
cloned.rsl = rsl.clone();
cloned.mem = mem.clone();
cloned.arr = arr.clone();
return cloned;
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}
}
}
> Add support for fast cryptographically secure pseudorandom number generator
> ISAAC
> ---------------------------------------------------------------------------------
>
> Key: MATH-710
> URL: https://issues.apache.org/jira/browse/MATH-710
> Project: Commons Math
> Issue Type: New Feature
> Affects Versions: 2.2
> Reporter: Eldar Agalarov
> Original Estimate: 1h
> Remaining Estimate: 1h
>
> Dear developers, please add to Common Math library support for ISAAC random
> number generator. This is a free and open-source PRNG
> (http://burtleburtle.net/bob/rand/isaacafa.html).
> Algorithm's rewrited (with some improvements) Java code from original C
> version is attached.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira