104 lines
2.8 KiB
C#
104 lines
2.8 KiB
C#
/************************** mersenne.cpp **********************************
|
|
* Author: Agner Fog
|
|
* Date created: 2001
|
|
* Last modified: 2008-11-16
|
|
* Project: randomc.h
|
|
* Platform: Any C++
|
|
* Description:
|
|
* Random Number generator of type 'Mersenne Twister'
|
|
*
|
|
* This random number generator is described in the article by
|
|
* M. Matsumoto & T. Nishimura, in:
|
|
* ACM Transactions on Modeling and Computer Simulation,
|
|
* vol. 8, no. 1, 1998, pp. 3-30.
|
|
* Details on the initialization scheme can be found at
|
|
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
|
*
|
|
* Further documentation:
|
|
* The file ran-instructions.pdf contains further documentation and
|
|
* instructions.
|
|
*
|
|
* Copyright 2001-2008 by Agner Fog.
|
|
* GNU General Public License http://www.gnu.org/licenses/gpl.html
|
|
*******************************************************************************/
|
|
|
|
// Only the methods I need have been ported to C#...
|
|
|
|
namespace de4dot.code.deobfuscators.CodeWall.randomc {
|
|
class CRandomMersenne {
|
|
const int MERS_N = 624;
|
|
const int MERS_M = 397;
|
|
const int MERS_R = 31;
|
|
const int MERS_U = 11;
|
|
const int MERS_S = 7;
|
|
const int MERS_T = 15;
|
|
const int MERS_L = 18;
|
|
const uint MERS_A = 0x9908B0DF;
|
|
const uint MERS_B = 0x9D2C5680;
|
|
const uint MERS_C = 0xEFC60000;
|
|
|
|
uint[] mt = new uint[MERS_N]; // State vector
|
|
int mti; // Index into mt
|
|
|
|
public CRandomMersenne() {
|
|
}
|
|
|
|
public CRandomMersenne(int seed) {
|
|
RandomInit(seed);
|
|
}
|
|
|
|
void Init0(int seed) {
|
|
// Seed generator
|
|
const uint factor = 1812433253;
|
|
mt[0] = (uint)seed;
|
|
for (mti = 1; mti < MERS_N; mti++) {
|
|
mt[mti] = (factor * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + (uint)mti);
|
|
}
|
|
}
|
|
|
|
public void RandomInit(int seed) {
|
|
// Initialize and seed
|
|
Init0(seed);
|
|
|
|
// Randomize some more
|
|
for (int i = 0; i < 37; i++) BRandom();
|
|
}
|
|
|
|
static uint[] mag01 = new uint[2] { 0, MERS_A };
|
|
public uint BRandom() {
|
|
// Generate 32 random bits
|
|
uint y;
|
|
|
|
if (mti >= MERS_N) {
|
|
// Generate MERS_N words at one time
|
|
const uint LOWER_MASK = (1U << MERS_R) - 1; // Lower MERS_R bits
|
|
const uint UPPER_MASK = 0xFFFFFFFF << MERS_R; // Upper (32 - MERS_R) bits
|
|
|
|
int kk;
|
|
for (kk = 0; kk < MERS_N - MERS_M; kk++) {
|
|
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
|
|
mt[kk] = mt[kk + MERS_M] ^ (y >> 1) ^ mag01[y & 1];
|
|
}
|
|
|
|
for (; kk < MERS_N - 1; kk++) {
|
|
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
|
|
mt[kk] = mt[kk + (MERS_M - MERS_N)] ^ (y >> 1) ^ mag01[y & 1];
|
|
}
|
|
|
|
y = (mt[MERS_N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
|
mt[MERS_N - 1] = mt[MERS_M - 1] ^ (y >> 1) ^ mag01[y & 1];
|
|
mti = 0;
|
|
}
|
|
y = mt[mti++];
|
|
|
|
// Tempering (May be omitted):
|
|
y ^= y >> MERS_U;
|
|
y ^= (y << MERS_S) & MERS_B;
|
|
y ^= (y << MERS_T) & MERS_C;
|
|
y ^= y >> MERS_L;
|
|
|
|
return y;
|
|
}
|
|
}
|
|
}
|