diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 56a90b1b5d..2d0b280bfe 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -3036,4 +3036,55 @@ namespace OpenSim.Framework } } } + + public class BetterRandom + { + private const int BufferSize = 1024; // must be a multiple of 4 + private byte[] RandomBuffer; + private int BufferOffset; + private RNGCryptoServiceProvider rng; + public BetterRandom() + { + RandomBuffer = new byte[BufferSize]; + rng = new RNGCryptoServiceProvider(); + BufferOffset = RandomBuffer.Length; + } + private void FillBuffer() + { + rng.GetBytes(RandomBuffer); + BufferOffset = 0; + } + public int Next() + { + if (BufferOffset >= RandomBuffer.Length) + { + FillBuffer(); + } + int val = BitConverter.ToInt32(RandomBuffer, BufferOffset) & 0x7fffffff; + BufferOffset += sizeof(int); + return val; + } + public int Next(int maxValue) + { + return Next() % maxValue; + } + public int Next(int minValue, int maxValue) + { + if (maxValue < minValue) + { + throw new ArgumentOutOfRangeException("maxValue must be greater than or equal to minValue"); + } + int range = maxValue - minValue; + return minValue + Next(range); + } + public double NextDouble() + { + int val = Next(); + return (double)val / int.MaxValue; + } + public void GetBytes(byte[] buff) + { + rng.GetBytes(buff); + } + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c5e02a61ab..53c198ec29 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5631,7 +5631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List llListRandomize(LSL_List src, int stride) { LSL_List result; - Random rand = new Random(); + BetterRandom rand = new BetterRandom(); int chunkk; int[] chunks; @@ -5647,24 +5647,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // If not, then return the src list. This also // traps those cases where stride > length. - if (src.Length != stride && src.Length%stride == 0) + if (src.Length != stride && src.Length % stride == 0) { chunkk = src.Length/stride; chunks = new int[chunkk]; for (int i = 0; i < chunkk; i++) + { chunks[i] = i; + } // Knuth shuffle the chunkk index - for (int i = chunkk - 1; i >= 1; i--) + for (int i = chunkk - 1; i > 0; i--) { // Elect an unrandomized chunk to swap int index = rand.Next(i + 1); - int tmp; // and swap position with first unrandomized chunk - tmp = chunks[i]; + int tmp = chunks[i]; chunks[i] = chunks[index]; chunks[index] = tmp; } @@ -5677,7 +5678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { for (int j = 0; j < stride; j++) { - result.Add(src.Data[chunks[i]*stride+j]); + result.Add(src.Data[chunks[i] * stride + j]); } } }