de4dot-cex/de4dot.code/deobfuscators/CodeWall/randomc/CRandomMersenne.cs
2012-05-26 05:26:00 +02:00

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;
}
}
}