From 1ab63a431663182599a43cbc1c313c4ce0fab144 Mon Sep 17 00:00:00 2001 From: jules Date: Sat, 6 Dec 2008 11:38:58 +0000 Subject: [PATCH] moved the BitArray::fillBitsRandomly() and BitArray::createRandomNumber() methods across to the Random class. --- juce_amalgamated.cpp | 94 ++-- juce_amalgamated.h | 610 +++++++++++---------- src/juce_core/basics/juce_Random.cpp | 43 +- src/juce_core/basics/juce_Random.h | 16 +- src/juce_core/basics/juce_SystemStats.cpp | 3 +- src/juce_core/containers/juce_BitArray.cpp | 40 -- src/juce_core/containers/juce_BitArray.h | 7 - src/juce_core/cryptography/juce_Primes.cpp | 15 +- 8 files changed, 414 insertions(+), 414 deletions(-) diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index d085e5b3e7..3da2fe2f88 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -804,7 +804,7 @@ void Random::setSeedRandomly() Random r3 (Time::getHighResolutionTicksPerSecond()); Random r4 (Time::currentTimeMillis()); - setSeed (r1.nextInt64() ^ r2.nextInt64() + setSeed (nextInt64() ^ r1.nextInt64() ^ r2.nextInt64() ^ r3.nextInt64() ^ r4.nextInt64()); } @@ -841,10 +841,43 @@ double Random::nextDouble() throw() return ((uint32) nextInt()) / (double) 0xffffffff; } -static Random sysRand (1); +const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +{ + BitArray n; + + do + { + fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); + } + while (n.compare (maximumValue) >= 0); + + return n; +} + +void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +{ + arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space + + while ((startBit & 31) != 0 && numBits > 0) + { + arrayToChange.setBit (startBit++, nextBool()); + --numBits; + } + + while (numBits >= 32) + { + arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); + startBit += 32; + numBits -= 32; + } + + while (--numBits >= 0) + arrayToChange.setBit (startBit + numBits, nextBool()); +} Random& Random::getSystemRandom() throw() { + static Random sysRand (1); return sysRand; } @@ -1123,9 +1156,10 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() juceInitialisedNonGUI = true; DBG (SystemStats::getJUCEVersion()); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) } } @@ -2395,45 +2429,6 @@ void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int v } } -void BitArray::fillBitsRandomly (int startBit, int numBits) throw() -{ - highestBit = jmax (highestBit, startBit + numBits); - ensureSize (((startBit + numBits) >> 5) + 1); - - while ((startBit & 31) != 0 && numBits > 0) - { - setBit (startBit++, Random::getSystemRandom().nextBool()); - - --numBits; - } - - while (numBits >= 32) - { - values [startBit >> 5] = (unsigned int) Random::getSystemRandom().nextInt(); - - startBit += 32; - numBits -= 32; - } - - while (--numBits >= 0) - { - setBit (startBit + numBits, Random::getSystemRandom().nextBool()); - } - - highestBit = getHighestBit(); -} - -void BitArray::createRandomNumber (const BitArray& maximumValue) throw() -{ - clear(); - - do - { - fillBitsRandomly (0, maximumValue.getHighestBit() + 1); - } - while (compare (maximumValue) >= 0); -} - bool BitArray::isNegative() const throw() { return negative && ! isEmpty(); @@ -4076,16 +4071,16 @@ const BitArray Primes::createProbablePrime (const int bitLength, const int* randomSeeds, int numRandomSeeds) throw() { - int defaultSeeds[8]; + int defaultSeeds [16]; if (numRandomSeeds <= 0) { randomSeeds = defaultSeeds; - numRandomSeeds = 8; + numRandomSeeds = numElementsInArray (defaultSeeds); + Random r (0); for (int j = 10; --j >= 0;) { - Random r (0); r.setSeedRandomly(); for (int i = numRandomSeeds; --i >= 0;) @@ -4101,15 +4096,14 @@ const BitArray Primes::createProbablePrime (const int bitLength, for (int i = numRandomSeeds; --i >= 0;) { - Random::getSystemRandom().setSeed (randomSeeds[i]); - BitArray p2; - p2.fillBitsRandomly (0, bitLength); + + Random r (randomSeeds[i]); + r.fillBitsRandomly (p2, 0, bitLength); + p.xorWith (p2); } - Random::getSystemRandom().setSeedRandomly(); - p.setBit (bitLength - 1); p.clearBit (0); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index c57643cf05..d2bf7fed1d 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -6991,6 +6991,302 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI(); #ifndef __JUCE_RANDOM_JUCEHEADER__ #define __JUCE_RANDOM_JUCEHEADER__ +/********* Start of inlined file: juce_BitArray.h *********/ +#ifndef __JUCE_BITARRAY_JUCEHEADER__ +#define __JUCE_BITARRAY_JUCEHEADER__ + +class MemoryBlock; + +/** + An array of on/off bits, also usable to store large binary integers. + + A BitArray acts like an arbitrarily large integer whose bits can be set or + cleared, and some basic mathematical operations can be done on the number as + a whole. +*/ +class JUCE_API BitArray +{ +public: + + /** Creates an empty BitArray */ + BitArray() throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 32 bits of the array are initialised with this value. + */ + BitArray (const unsigned int value) throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 32 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. + */ + BitArray (const int value) throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 64 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. + */ + BitArray (int64 value) throw(); + + /** Creates a copy of another BitArray. */ + BitArray (const BitArray& other) throw(); + + /** Destructor. */ + ~BitArray() throw(); + + /** Copies another BitArray onto this one. */ + const BitArray& operator= (const BitArray& other) throw(); + + /** Two arrays are the same if the same bits are set. */ + bool operator== (const BitArray& other) const throw(); + /** Two arrays are the same if the same bits are set. */ + bool operator!= (const BitArray& other) const throw(); + + /** Clears all bits in the BitArray to 0. */ + void clear() throw(); + + /** Clears a particular bit in the array. */ + void clearBit (const int bitNumber) throw(); + + /** Sets a specified bit to 1. + + If the bit number is high, this will grow the array to accomodate it. + */ + void setBit (const int bitNumber) throw(); + + /** Sets or clears a specified bit. */ + void setBit (const int bitNumber, + const bool shouldBeSet) throw(); + + /** Sets a range of bits to be either on or off. + + @param startBit the first bit to change + @param numBits the number of bits to change + @param shouldBeSet whether to turn these bits on or off + */ + void setRange (int startBit, + int numBits, + const bool shouldBeSet) throw(); + + /** Inserts a bit an a given position, shifting up any bits above it. */ + void insertBit (const int bitNumber, + const bool shouldBeSet) throw(); + + /** Returns the value of a specified bit in the array. + + If the index is out-of-range, the result will be false. + */ + bool operator[] (const int bit) const throw(); + + /** Returns true if no bits are set. */ + bool isEmpty() const throw(); + + /** Returns a range of bits in the array as an integer value. + + e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. + + Asking for more than 32 bits isn't allowed (obviously). + */ + int getBitRangeAsInt (int startBit, int numBits) const throw(); + + /** Sets a range of bits in the array based on an integer value. + + Copies the given integer into the array, starting at startBit, + and only using up to numBits of the available bits. + */ + void setBitRangeAsInt (int startBit, int numBits, + unsigned int valueToSet) throw(); + + /** Performs a bitwise OR with another BitArray. + + The result ends up in this array. + */ + void orWith (const BitArray& other) throw(); + + /** Performs a bitwise AND with another BitArray. + + The result ends up in this array. + */ + void andWith (const BitArray& other) throw(); + + /** Performs a bitwise XOR with another BitArray. + + The result ends up in this array. + */ + void xorWith (const BitArray& other) throw(); + + /** Adds another BitArray's value to this one. + + Treating the two arrays as large positive integers, this + adds them up and puts the result in this array. + */ + void add (const BitArray& other) throw(); + + /** Subtracts another BitArray's value from this one. + + Treating the two arrays as large positive integers, this + subtracts them and puts the result in this array. + + Note that if the result should be negative, this won't be + handled correctly. + */ + void subtract (const BitArray& other) throw(); + + /** Multiplies another BitArray's value with this one. + + Treating the two arrays as large positive integers, this + multiplies them and puts the result in this array. + */ + void multiplyBy (const BitArray& other) throw(); + + /** Divides another BitArray's value into this one and also produces a remainder. + + Treating the two arrays as large positive integers, this + divides this value by the other, leaving the quotient in this + array, and the remainder is copied into the other BitArray passed in. + */ + void divideBy (const BitArray& divisor, BitArray& remainder) throw(); + + /** Returns the largest value that will divide both this value and the one + passed-in. + */ + const BitArray findGreatestCommonDivisor (BitArray other) const throw(); + + /** Performs a modulo operation on this value. + + The result is stored in this value. + */ + void modulo (const BitArray& divisor) throw(); + + /** Performs a combined exponent and modulo operation. + + This BitArray's value becomes (this ^ exponent) % modulus. + */ + void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); + + /** Performs an inverse modulo on the value. + + i.e. the result is (this ^ -1) mod (modulus). + */ + void inverseModulo (const BitArray& modulus) throw(); + + /** Shifts a section of bits left or right. + + @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). + @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. + */ + void shiftBits (int howManyBitsLeft, + int startBit = 0) throw(); + + /** Does a signed comparison of two BitArrays. + + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compare (const BitArray& other) const throw(); + + /** Compares the magnitudes of two BitArrays, ignoring their signs. + + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compareAbsolute (const BitArray& other) const throw(); + + /** Returns true if the value is less than zero. + + @see setNegative, negate + */ + bool isNegative() const throw(); + + /** Changes the sign of the number to be positive or negative. + + @see isNegative, negate + */ + void setNegative (const bool shouldBeNegative) throw(); + + /** Inverts the sign of the number. + + @see isNegative, setNegative + */ + void negate() throw(); + + /** Counts the total number of set bits in the array. */ + int countNumberOfSetBits() const throw(); + + /** Looks for the index of the next set bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first set bit, + and returns its index. + + If no set bits are found, it returns -1. + */ + int findNextSetBit (int startIndex = 0) const throw(); + + /** Looks for the index of the next clear bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first clear bit, + and returns its index. + */ + int findNextClearBit (int startIndex = 0) const throw(); + + /** Returns the index of the highest set bit in the array. + + If the array is empty, this will return -1. + */ + int getHighestBit() const throw(); + + /** Converts the array to a number string. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + */ + const String toString (const int base) const throw(); + + /** Converts a number string to an array. + + Any non-valid characters will be ignored. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + */ + void parseString (const String& text, + const int base) throw(); + + /** Turns the array into a block of binary data. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see loadFromMemoryBlock + */ + const MemoryBlock toMemoryBlock() const throw(); + + /** Copies a block of raw data onto this array. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see toMemoryBlock + */ + void loadFromMemoryBlock (const MemoryBlock& data) throw(); + + juce_UseDebuggingNewOperator + +private: + void ensureSize (const int numVals) throw(); + unsigned int* values; + int numValues, highestBit; + bool negative; +}; + +#endif // __JUCE_BITARRAY_JUCEHEADER__ +/********* End of inlined file: juce_BitArray.h *********/ + /** A simple pseudo-random number generator. */ @@ -7045,6 +7341,15 @@ public: */ bool nextBool() throw(); + /** Returns a BitArray containing a random number. + + @returns a random value in the range 0 to (maximumValue - 1). + */ + const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + + /** Sets a range of bits in a BitArray to random values. */ + void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + /** To avoid the overhead of having to create a new Random object whenever you need a number, this is a shared application-wide object that can be used. @@ -7058,6 +7363,9 @@ public: /** Reseeds this generator using a value generated from various semi-random system properties like the current time, etc. + + Because this function convolves the time with the last seed value, calling + it repeatedly will increase the randomness of the final result. */ void setSeedRandomly(); @@ -7615,308 +7923,6 @@ public: #endif #ifndef __JUCE_BITARRAY_JUCEHEADER__ -/********* Start of inlined file: juce_BitArray.h *********/ -#ifndef __JUCE_BITARRAY_JUCEHEADER__ -#define __JUCE_BITARRAY_JUCEHEADER__ - -class MemoryBlock; - -/** - An array of on/off bits, also usable to store large binary integers. - - A BitArray acts like an arbitrarily large integer whose bits can be set or - cleared, and some basic mathematical operations can be done on the number as - a whole. -*/ -class JUCE_API BitArray -{ -public: - - /** Creates an empty BitArray */ - BitArray() throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with this value. - */ - BitArray (const unsigned int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (const int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 64 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (int64 value) throw(); - - /** Creates a copy of another BitArray. */ - BitArray (const BitArray& other) throw(); - - /** Destructor. */ - ~BitArray() throw(); - - /** Copies another BitArray onto this one. */ - const BitArray& operator= (const BitArray& other) throw(); - - /** Two arrays are the same if the same bits are set. */ - bool operator== (const BitArray& other) const throw(); - /** Two arrays are the same if the same bits are set. */ - bool operator!= (const BitArray& other) const throw(); - - /** Clears all bits in the BitArray to 0. */ - void clear() throw(); - - /** Clears a particular bit in the array. */ - void clearBit (const int bitNumber) throw(); - - /** Sets a specified bit to 1. - - If the bit number is high, this will grow the array to accomodate it. - */ - void setBit (const int bitNumber) throw(); - - /** Sets or clears a specified bit. */ - void setBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Sets a range of bits to be either on or off. - - @param startBit the first bit to change - @param numBits the number of bits to change - @param shouldBeSet whether to turn these bits on or off - */ - void setRange (int startBit, - int numBits, - const bool shouldBeSet) throw(); - - /** Inserts a bit an a given position, shifting up any bits above it. */ - void insertBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Returns the value of a specified bit in the array. - - If the index is out-of-range, the result will be false. - */ - bool operator[] (const int bit) const throw(); - - /** Returns true if no bits are set. */ - bool isEmpty() const throw(); - - /** Returns a range of bits in the array as an integer value. - - e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. - - Asking for more than 32 bits isn't allowed (obviously). - */ - int getBitRangeAsInt (int startBit, int numBits) const throw(); - - /** Sets a range of bits in the array based on an integer value. - - Copies the given integer into the array, starting at startBit, - and only using up to numBits of the available bits. - */ - void setBitRangeAsInt (int startBit, int numBits, - unsigned int valueToSet) throw(); - - /** Performs a bitwise OR with another BitArray. - - The result ends up in this array. - */ - void orWith (const BitArray& other) throw(); - - /** Performs a bitwise AND with another BitArray. - - The result ends up in this array. - */ - void andWith (const BitArray& other) throw(); - - /** Performs a bitwise XOR with another BitArray. - - The result ends up in this array. - */ - void xorWith (const BitArray& other) throw(); - - /** Adds another BitArray's value to this one. - - Treating the two arrays as large positive integers, this - adds them up and puts the result in this array. - */ - void add (const BitArray& other) throw(); - - /** Subtracts another BitArray's value from this one. - - Treating the two arrays as large positive integers, this - subtracts them and puts the result in this array. - - Note that if the result should be negative, this won't be - handled correctly. - */ - void subtract (const BitArray& other) throw(); - - /** Multiplies another BitArray's value with this one. - - Treating the two arrays as large positive integers, this - multiplies them and puts the result in this array. - */ - void multiplyBy (const BitArray& other) throw(); - - /** Divides another BitArray's value into this one and also produces a remainder. - - Treating the two arrays as large positive integers, this - divides this value by the other, leaving the quotient in this - array, and the remainder is copied into the other BitArray passed in. - */ - void divideBy (const BitArray& divisor, BitArray& remainder) throw(); - - /** Returns the largest value that will divide both this value and the one - passed-in. - */ - const BitArray findGreatestCommonDivisor (BitArray other) const throw(); - - /** Performs a modulo operation on this value. - - The result is stored in this value. - */ - void modulo (const BitArray& divisor) throw(); - - /** Performs a combined exponent and modulo operation. - - This BitArray's value becomes (this ^ exponent) % modulus. - */ - void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); - - /** Performs an inverse modulo on the value. - - i.e. the result is (this ^ -1) mod (modulus). - */ - void inverseModulo (const BitArray& modulus) throw(); - - /** Shifts a section of bits left or right. - - @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). - @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. - */ - void shiftBits (int howManyBitsLeft, - int startBit = 0) throw(); - - /** Does a signed comparison of two BitArrays. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compare (const BitArray& other) const throw(); - - /** Compares the magnitudes of two BitArrays, ignoring their signs. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compareAbsolute (const BitArray& other) const throw(); - - /** Returns true if the value is less than zero. - - @see setNegative, negate - */ - bool isNegative() const throw(); - - /** Changes the sign of the number to be positive or negative. - - @see isNegative, negate - */ - void setNegative (const bool shouldBeNegative) throw(); - - /** Inverts the sign of the number. - - @see isNegative, setNegative - */ - void negate() throw(); - - /** Counts the total number of set bits in the array. */ - int countNumberOfSetBits() const throw(); - - /** Looks for the index of the next set bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first set bit, - and returns its index. - - If no set bits are found, it returns -1. - */ - int findNextSetBit (int startIndex = 0) const throw(); - - /** Looks for the index of the next clear bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first clear bit, - and returns its index. - */ - int findNextClearBit (int startIndex = 0) const throw(); - - /** Returns the index of the highest set bit in the array. - - If the array is empty, this will return -1. - */ - int getHighestBit() const throw(); - - /** Sets a range of bits to random values. */ - void fillBitsRandomly (int startBit, int numBits) throw(); - - /** Turns this value into a random number less than the given value. */ - void createRandomNumber (const BitArray& maximumValue) throw(); - - /** Converts the array to a number string. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - */ - const String toString (const int base) const throw(); - - /** Converts a number string to an array. - - Any non-valid characters will be ignored. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - */ - void parseString (const String& text, - const int base) throw(); - - /** Turns the array into a block of binary data. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. - - @see loadFromMemoryBlock - */ - const MemoryBlock toMemoryBlock() const throw(); - - /** Copies a block of raw data onto this array. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. - - @see toMemoryBlock - */ - void loadFromMemoryBlock (const MemoryBlock& data) throw(); - - juce_UseDebuggingNewOperator - -private: - void ensureSize (const int numVals) throw(); - unsigned int* values; - int numValues, highestBit; - bool negative; -}; - -#endif // __JUCE_BITARRAY_JUCEHEADER__ -/********* End of inlined file: juce_BitArray.h *********/ - #endif #ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ diff --git a/src/juce_core/basics/juce_Random.cpp b/src/juce_core/basics/juce_Random.cpp index 64b02ad95f..9f5ec7ed59 100644 --- a/src/juce_core/basics/juce_Random.cpp +++ b/src/juce_core/basics/juce_Random.cpp @@ -34,8 +34,8 @@ BEGIN_JUCE_NAMESPACE #include "juce_Random.h" -#include "../basics/juce_Time.h" -#include "../basics/juce_SystemStats.h" +#include "juce_Time.h" +#include "juce_SystemStats.h" //============================================================================== @@ -60,7 +60,7 @@ void Random::setSeedRandomly() Random r3 (Time::getHighResolutionTicksPerSecond()); Random r4 (Time::currentTimeMillis()); - setSeed (r1.nextInt64() ^ r2.nextInt64() + setSeed (nextInt64() ^ r1.nextInt64() ^ r2.nextInt64() ^ r3.nextInt64() ^ r4.nextInt64()); } @@ -98,11 +98,44 @@ double Random::nextDouble() throw() return ((uint32) nextInt()) / (double) 0xffffffff; } -//============================================================================== -static Random sysRand (1); +const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +{ + BitArray n; + do + { + fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); + } + while (n.compare (maximumValue) >= 0); + + return n; +} + +void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +{ + arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space + + while ((startBit & 31) != 0 && numBits > 0) + { + arrayToChange.setBit (startBit++, nextBool()); + --numBits; + } + + while (numBits >= 32) + { + arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); + startBit += 32; + numBits -= 32; + } + + while (--numBits >= 0) + arrayToChange.setBit (startBit + numBits, nextBool()); +} + +//============================================================================== Random& Random::getSystemRandom() throw() { + static Random sysRand (1); return sysRand; } diff --git a/src/juce_core/basics/juce_Random.h b/src/juce_core/basics/juce_Random.h index b85c294a8f..50c7e2f0aa 100644 --- a/src/juce_core/basics/juce_Random.h +++ b/src/juce_core/basics/juce_Random.h @@ -32,6 +32,8 @@ #ifndef __JUCE_RANDOM_JUCEHEADER__ #define __JUCE_RANDOM_JUCEHEADER__ +#include "../containers/juce_BitArray.h" + //============================================================================== /** @@ -88,6 +90,15 @@ public: */ bool nextBool() throw(); + /** Returns a BitArray containing a random number. + + @returns a random value in the range 0 to (maximumValue - 1). + */ + const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + + /** Sets a range of bits in a BitArray to random values. */ + void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + //============================================================================== /** To avoid the overhead of having to create a new Random object whenever you need a number, this is a shared application-wide object that @@ -100,8 +111,11 @@ public: /** Resets this Random object to a given seed value. */ void setSeed (const int64 newSeed) throw(); - /** Reseeds this generator using a value generated from various semi-random system + /** Reseeds this generator using a value generated from various semi-random system properties like the current time, etc. + + Because this function convolves the time with the last seed value, calling + it repeatedly will increase the randomness of the final result. */ void setSeedRandomly(); diff --git a/src/juce_core/basics/juce_SystemStats.cpp b/src/juce_core/basics/juce_SystemStats.cpp index 6209c6e326..7cf50da0b2 100644 --- a/src/juce_core/basics/juce_SystemStats.cpp +++ b/src/juce_core/basics/juce_SystemStats.cpp @@ -84,9 +84,10 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() juceInitialisedNonGUI = true; DBG (SystemStats::getJUCEVersion()); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) } } diff --git a/src/juce_core/containers/juce_BitArray.cpp b/src/juce_core/containers/juce_BitArray.cpp index 1e6a85b6bd..b6b681f5c2 100644 --- a/src/juce_core/containers/juce_BitArray.cpp +++ b/src/juce_core/containers/juce_BitArray.cpp @@ -736,46 +736,6 @@ void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int v } } -//============================================================================== -void BitArray::fillBitsRandomly (int startBit, int numBits) throw() -{ - highestBit = jmax (highestBit, startBit + numBits); - ensureSize (((startBit + numBits) >> 5) + 1); - - while ((startBit & 31) != 0 && numBits > 0) - { - setBit (startBit++, Random::getSystemRandom().nextBool()); - - --numBits; - } - - while (numBits >= 32) - { - values [startBit >> 5] = (unsigned int) Random::getSystemRandom().nextInt(); - - startBit += 32; - numBits -= 32; - } - - while (--numBits >= 0) - { - setBit (startBit + numBits, Random::getSystemRandom().nextBool()); - } - - highestBit = getHighestBit(); -} - -void BitArray::createRandomNumber (const BitArray& maximumValue) throw() -{ - clear(); - - do - { - fillBitsRandomly (0, maximumValue.getHighestBit() + 1); - } - while (compare (maximumValue) >= 0); -} - //============================================================================== bool BitArray::isNegative() const throw() { diff --git a/src/juce_core/containers/juce_BitArray.h b/src/juce_core/containers/juce_BitArray.h index 3b63967954..8757821346 100644 --- a/src/juce_core/containers/juce_BitArray.h +++ b/src/juce_core/containers/juce_BitArray.h @@ -289,13 +289,6 @@ public: */ int getHighestBit() const throw(); - //============================================================================== - /** Sets a range of bits to random values. */ - void fillBitsRandomly (int startBit, int numBits) throw(); - - /** Turns this value into a random number less than the given value. */ - void createRandomNumber (const BitArray& maximumValue) throw(); - //============================================================================== /** Converts the array to a number string. diff --git a/src/juce_core/cryptography/juce_Primes.cpp b/src/juce_core/cryptography/juce_Primes.cpp index 23a078cf1c..3bb7a7f063 100644 --- a/src/juce_core/cryptography/juce_Primes.cpp +++ b/src/juce_core/cryptography/juce_Primes.cpp @@ -126,16 +126,16 @@ const BitArray Primes::createProbablePrime (const int bitLength, const int* randomSeeds, int numRandomSeeds) throw() { - int defaultSeeds[8]; + int defaultSeeds [16]; if (numRandomSeeds <= 0) { randomSeeds = defaultSeeds; - numRandomSeeds = 8; + numRandomSeeds = numElementsInArray (defaultSeeds); + Random r (0); for (int j = 10; --j >= 0;) { - Random r (0); r.setSeedRandomly(); for (int i = numRandomSeeds; --i >= 0;) @@ -151,15 +151,14 @@ const BitArray Primes::createProbablePrime (const int bitLength, for (int i = numRandomSeeds; --i >= 0;) { - Random::getSystemRandom().setSeed (randomSeeds[i]); - BitArray p2; - p2.fillBitsRandomly (0, bitLength); + + Random r (randomSeeds[i]); + r.fillBitsRandomly (p2, 0, bitLength); + p.xorWith (p2); } - Random::getSystemRandom().setSeedRandomly(); - p.setBit (bitLength - 1); p.clearBit (0);