forked from ppy/osu-stream
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFastRandom.cs
More file actions
98 lines (88 loc) · 2.7 KB
/
FastRandom.cs
File metadata and controls
98 lines (88 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System;
namespace StreamFormatDecryptor
{
/// <summary>
/// A fast random number generator for .NET
/// Based on the xorshift pseudo random number generator (RNG) specified in:
/// Marsaglia, George. (2003). Xorshift RNGs.
/// period of 2^128-1
/// </summary>
public class FastRandom
{
private const double REAL_UNIT_INT = 1.0 / (int.MaxValue + 1.0);
private const double REAL_UNIT_UINT = 1.0 / (uint.MaxValue + 1.0);
private const uint W = 273326509;
private const uint Y = 842502087, Z = 3579807591;
private uint w;
private uint x, y, z;
private uint bitBuffer;
private int bitBufferIdx = 32;
public FastRandom()
{
Reinitialise(Environment.TickCount);
}
public FastRandom(int seed)
{
Reinitialise(seed);
}
public void Reinitialise(int seed)
{
x = (uint)seed;
y = Y;
z = Z;
w = W;
bitBufferIdx = 32;
}
public uint NextUInt()
{
uint t = (x ^ (x << 11));
x = y;
y = z;
z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
public void NextBytes(byte[] buffer)
{
uint x = this.x, y = this.y, z = this.z, w = this.w;
int i = 0;
uint t;
for (; i < buffer.Length - 3;)
{
t = (x ^ (x << 11));
x = y;
y = z;
z = w;
w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
buffer[i++] = (byte)(w & 0x000000FF);
buffer[i++] = (byte)((w & 0x0000FF00) >> 8);
buffer[i++] = (byte)((w & 0x00FF0000) >> 16);
buffer[i++] = (byte)((w & 0xFF000000) >> 24);
}
if (i < buffer.Length)
{
t = (x ^ (x << 11));
x = y;
y = z;
z = w;
w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
buffer[i++] = (byte)(w & 0x000000FF);
if (i < buffer.Length)
{
buffer[i++] = (byte)((w & 0x0000FF00) >> 8);
if (i < buffer.Length)
{
buffer[i++] = (byte)((w & 0x00FF0000) >> 16);
if (i < buffer.Length)
{
buffer[i] = (byte)((w & 0xFF000000) >> 24);
}
}
}
}
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}
}