Package squidpony.squidmath
Class LFSR
java.lang.Object
squidpony.squidmath.LFSR
- All Implemented Interfaces:
Serializable
,RandomnessSource
,StatefulRandomness
public class LFSR extends Object implements StatefulRandomness, Serializable
A Linear Feedback Shift Register that may be used like a StatefulRandomness but is not truly random. This has a
period of (2 to the 64) minus 1, and is based on Wikipedia's code for a Galois LFSR but uses data from
http://web.archive.org/web/20161007061934/http://courses.cse.tamu.edu/csce680/walker/lfsr_table.pdf .
It is important to note that an LFSR will produce each number from 1 until its maximum exactly once before repeating,
so this may be useful as a way of generating test data in an unpredictable order.
- Author:
- Tommy Ettinger
- See Also:
- Serialized Form
-
Field Summary
Fields Modifier and Type Field Description long
state
-
Constructor Summary
Constructors Constructor Description LFSR()
Creates a new generator seeded using Math.random.LFSR(long seed)
LFSR(CharSequence seed)
-
Method Summary
Modifier and Type Method Description LFSR
copy()
Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called.static long
determine(long state)
Gets the next number that an LFSR would produce usingnextLong()
if its state wasstate
.static int
determineBounded(int state, int bound)
Gets an int usingdetermineInt(int)
and bounds it to fit between 0 (inclusive) and bound (exclusive).static int
determineBounded(long state, int bound)
Gets the next number that an LFSR would produce usingnextInt(int)
if its state wasstate
andbound
was passed to nextInt().static int
determineByte(byte state)
Gets the next number from 1 to 255 that a different kind of LFSR would produce if its state wasstate
.static int
determineInt(int state)
Gets the next number that a different kind of 32-bit LFSR would produce if its state wasstate
.static int
determineIntSymmetrical(int state)
Gets the next int that a different kind of LFSR would produce if its state wasstate
.static int
determinePositiveInt(int state)
Gets the next positive int that a different kind of 31-bit LFSR would produce if its state wasstate
.static long
determinePositiveLong(long state)
Gets the next positive long that a different kind of 63-bit LFSR would produce if its state wasstate
.boolean
equals(Object o)
long
getState()
Get the current internal state of the StatefulRandomness as a long.int
hashCode()
int
next(int bits)
Using this method, any algorithm that might use the built-in Java Random can interface with this randomness source.boolean
nextBoolean()
void
nextBytes(byte[] bytes)
double
nextDouble()
float
nextFloat()
int
nextInt()
Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.int
nextInt(int bound)
Exclusive on the outer bound; the inner bound is 0.int
nextInt(int inner, int outer)
Inclusive lower, exclusive upper.long
nextLong()
Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source.long
nextLong(long bound)
Exclusive on the outer bound; the inner bound is 0.long
nextLong(long inner, long outer)
Inclusive inner, exclusive outer; both inner and outer can be positive or negative.void
setState(long seed)
Sets the seed of this generator using one long, running that through LightRNG's algorithm twice to get the state.String
toString()
-
Field Details
-
Constructor Details
-
Method Details
-
next
Description copied from interface:RandomnessSource
Using this method, any algorithm that might use the built-in Java Random can interface with this randomness source.- Specified by:
next
in interfaceRandomnessSource
- Parameters:
bits
- the number of bits to be returned- Returns:
- the integer containing the appropriate number of bits
-
nextLong
Description copied from interface:RandomnessSource
Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source. Get a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive).- Specified by:
nextLong
in interfaceRandomnessSource
- Returns:
- a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive)
-
copy
Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called. This just needs to copy the state so it isn't shared, usually, and produce a new value with the same exact state.- Specified by:
copy
in interfaceRandomnessSource
- Specified by:
copy
in interfaceStatefulRandomness
- Returns:
- a copy of this RandomnessSource
-
nextInt
Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.- Returns:
- any int, all 32 bits are random
-
nextInt
Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive result.- Parameters:
bound
- the outer exclusive bound; may be positive or negative- Returns:
- a random long between 0 (inclusive) and bound (exclusive)
-
nextInt
Inclusive lower, exclusive upper.- Parameters:
inner
- the inner bound, inclusive, can be positive or negativeouter
- the outer bound, exclusive, should be positive, should usually be greater than inner- Returns:
- a random int that may be equal to inner and will otherwise be between inner and outer
-
nextLong
Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive result.- Parameters:
bound
- the outer exclusive bound; may be positive or negative- Returns:
- a random long between 0 (inclusive) and bound (exclusive)
-
nextLong
Inclusive inner, exclusive outer; both inner and outer can be positive or negative.- Parameters:
inner
- the inner bound, inclusive, can be positive or negativeouter
- the outer bound, exclusive, can be positive or negative and may be greater than or less than inner- Returns:
- a random long that may be equal to inner and will otherwise be between inner and outer
-
nextDouble
-
nextFloat
-
nextBoolean
-
nextBytes
-
getState
Get the current internal state of the StatefulRandomness as a long.- Specified by:
getState
in interfaceStatefulRandomness
- Returns:
- the current internal state of this object.
-
setState
Sets the seed of this generator using one long, running that through LightRNG's algorithm twice to get the state.- Specified by:
setState
in interfaceStatefulRandomness
- Parameters:
seed
- the number to use as the seed
-
toString
-
equals
-
hashCode
-
determine
Gets the next number that an LFSR would produce usingnextLong()
if its state wasstate
. Does not allow state to be 0. Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determine(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of ((2 to the 64) minus 1), or the guarantee that every number from 1 to ((2 to the 64) minus 1), inclusive on both, will be generated once per period).- Parameters:
state
- any long other than 0- Returns:
- the next long that a 64-bit LFSR would produce with the given state
-
determineByte
Gets the next number from 1 to 255 that a different kind of LFSR would produce if its state wasstate
. Does not allow state to be 0. If given all byte values except 0 as arguments, will produce all ints 1-255. Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determineByte(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of 255, or the guarantee that every number from 1 to 255, inclusive on both, will be generated once per period).- Parameters:
state
- any byte other than 0- Returns:
- the next int between 1 and 255 that an 8-bit LFSR would produce with the given state
-
determineInt
Gets the next number that a different kind of 32-bit LFSR would produce if its state wasstate
. Does not allow state to be 0. If given all int values except 0 as arguments, will produce all ints except 0. Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determineInt(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of ((2 to the 32) minus 1), or the guarantee that every number from 1 to ((2 to the 32) minus 1), inclusive on both, will be generated once per period).- Parameters:
state
- any long other than 0- Returns:
- the next int that a 32-bit LFSR would produce with the given state
-
determinePositiveLong
Gets the next positive long that a different kind of 63-bit LFSR would produce if its state wasstate
. Does not allow state to be 0 or negative. If given all positive long values (not including 0) as arguments, will produce all longs greater than 0. Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determinePositiveLong(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of ((2 to the 63) minus 1), or the guarantee that every number from 1 to ((2 to the 63) minus 1), inclusive on both, will be generated once per period).- Parameters:
state
- any positive long, not including 0- Returns:
- the next int that a 63-bit LFSR would produce with the given state
-
determinePositiveInt
Gets the next positive int that a different kind of 31-bit LFSR would produce if its state wasstate
. Does not allow state to be 0 or negative. If given all positive int values (not including 0) as arguments, will produce all ints greater than 0. Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determinePositiveInt(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of ((2 to the 31) minus 1), or the guarantee that every number from 1 to ((2 to the 31) minus 1), inclusive on both, will be generated once per period).
A potential benefit of using this particular LFSR type is that the period is a prime number, 2147483647; this can sometimes be relevant if you simultaneously get pseudo-random numbers from sources of randomness with different periods that are "relatively co-prime" (that is, they share no common factors other than 1). This case lengthens the total period of the combined generators significantly, generally multiplying the periods together to get the combined period, as opposed to other cases that may simply add them together.- Parameters:
state
- any positive int, not including 0- Returns:
- the next int that a 31-bit LFSR would produce with the given state
-
determineIntSymmetrical
Gets the next int that a different kind of LFSR would produce if its state wasstate
. Does not allow state to beInteger.MIN_VALUE
, nor will this produce a result ofInteger.MIN_VALUE
(as long asInteger.MIN_VALUE
was not the input). If given all int values exceptInteger.MIN_VALUE
as arguments, will produce all ints in the range[-2147483647,2147483647]
, including 0 but not -2147483648 (the minimum int). Strongly consider using the result of this and assigning it to state if you expect to call this again, such as with(state = LFSR.determineIntSymmetrical(state))
, which will ensure the long-term properties of an LFSR hold up (such as having a period of ((2 to the 32) minus 1), or the guarantee that every int exceptInteger.MIN_VALUE
will be generated once per period).
This is called Symmetrical because it produces the same amount of positive and negative numbers, instead of the normal generation of more negative ones (due to how ints are represented, the min value is always further from 0 than the max value for any signed integer type).- Parameters:
state
- any int other than -2147483648 (0x80000000), which isInteger.MIN_VALUE
; can produce 0- Returns:
- the next int other than -2147483648 that an LFSR would produce with the given state
-
determineBounded
Gets the next number that an LFSR would produce usingnextInt(int)
if its state wasstate
andbound
was passed to nextInt(). Does not allow state to be 0, but bound can be negative, which causes this not to produce positive numbers. This method is very predictable and its use is not encouraged; prefer usingdetermineBounded(int, int)
.- Parameters:
state
- any long other than 0bound
- the exclusive bound on the result as an int; does better if the bound is not too high (below 10000?)- Returns:
- the next value that
determine(long)
would produce with the given state, but limited to bound; can return 0
-
determineBounded
Gets an int usingdetermineInt(int)
and bounds it to fit between 0 (inclusive) and bound (exclusive). Does not allow state to be 0, but bound can be negative, which causes this not to produce positive numbers.- Parameters:
state
- any int other than 0bound
- the exclusive bound on the result as an int; does better if the bound is not too high (below 10000?)- Returns:
- the next int that
determineInt(int)
would produce with the given state, but limited to bound; can return 0
-