-
Notifications
You must be signed in to change notification settings - Fork 0
/
pseudoRandomc.cs
172 lines (161 loc) · 5.34 KB
/
pseudoRandomc.cs
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Universal Cross-Platform Multi-Language Pseudo Random Number Generator (pseudoRandom) v0.9
*
* A Set of libraries for Pseudo-Random Number Generation across environments
*
* X-PRNG is an advanced set of libraries designed to provide developers with tools
* for generating pseudo-random numbers across various computing environments. It
* supports a wide range of applications, from statistical analysis and data simulation
* to secure cryptographic functions. These libraries offer a simple yet powerful
* interface for incorporating high-quality, pseudo-random numbers into applications
* written in different programming languages, ensuring consistency and reliability
* across platforms.
*
* Copyright (C) 2024 under GPL v. 2 license
* 18 March 2024
*
* @author Luca Soltoggio
* https://www.lucasoltoggio.it
* https://github.com/toggio/X-PRNG
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
*
* PseudoRandom Number Generator C# Class
*
* This class implements a pseudo-random number generator (PRNG) using a linear
* congruential generator (LCG) algorithm.
*
*/
using System;
using System.Text;
public class pseudoRandom
{
private static ulong _savedRSeed;
private static ulong _RSeed = 0;
private const ulong _a = 1664525; // Multiplier
private static ulong _c = 1013904223; // Increment
private const ulong _m = 4294967296; // Modulus (2^32)
private static int _counter = 0;
/**
* Constructor to initialize the PRNG with an optional seed.
* If a string is provided as a seed, it uses crc32 to convert it into an unsigned integer.
* If no seed is provided, it uses the current Unix time.
*
* @param seed Optional seed for the PRNG, can be a string or a uint.
*/
public pseudoRandom(object? seed = null)
{
reSeed(seed);
}
/**
* Function to re-seed the PRNG. This can be used to reset the generator's state.
*
* @param seed Optional new seed for the PRNG, can be a string or a uint.
*/
public void reSeed(object seed = null)
{
if (seed is string strSeed)
{
// Convert the string to uint using CRC32 if the seed is a string
_RSeed = (ulong)crc32(Encoding.UTF8.GetBytes(strSeed)) & 0xFFFFFFFF;
}
else if (seed is uint uintSeed)
{
_RSeed = uintSeed;
}
else
{
// Set an initial seed based on the current Unix time if none provided
_RSeed = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
}
_counter = 0;
}
/**
* Saves the current state of the PRNG for later restoration.
*/
public void saveState()
{
_savedRSeed = _RSeed;
}
/**
* Restores the PRNG to a previously saved state.
*/
public void restoreState()
{
_RSeed = _savedRSeed;
}
/**
* Generates a pseudo-random integer within a specified range.
*
* @param min The lower bound of the range (inclusive).
* @param max The upper bound of the range (inclusive).
* @return A pseudo-random integer between min and max.
*/
public int randInt(int min = 0, int max = 255)
{
string counterSeedString = _counter.ToString() + _RSeed.ToString() + _counter.ToString();
_c = crc32(Encoding.UTF8.GetBytes(counterSeedString));
_RSeed = (_RSeed * _a + _c) % _m;
_counter++;
return (int)((_RSeed / (float)_m) * (max - min + 1) + min);
}
/**
* Generates a string of pseudo-random bytes of a specified length.
*
* @param length The length of the byte string.
* @param readable If true, ensures the generated bytes are in the readable ASCII range.
* @return A byte array of pseudo-random bytes.
*/
public byte[] randBytes(int length = 1, bool readable = false)
{
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++)
{
int n = readable ? randInt(32, 126) : randInt(0, 255);
bytes[i] = (byte)n;
}
return bytes;
}
/**
* CRC32 Hashing Function
*
* @param data Input data for CRC32 computation.
* @return CRC32 hash as an unsigned integer.
*/
private uint crc32(byte[] data)
{
uint[] table = new uint[256];
const uint polynomial = 0xedb88320;
for (uint i = 0; i < table.Length; ++i)
{
uint crc = i;
for (uint j = 8; j > 0; --j)
{
if ((crc & 1) == 1)
crc = (crc >> 1) ^ polynomial;
else
crc >>= 1;
}
table[i] = crc;
}
uint _crc32 = 0xffffffff;
foreach (byte b in data)
{
byte index = (byte)(((_crc32) & 0xff) ^ b);
_crc32 = (_crc32 >> 8) ^ table[index];
}
return ~_crc32;
}
}