CryptoByLeo/Src/URandom/PRNG.mqh

177 lines
5.9 KiB
MQL5

2026-09-01 12:16:15 -05:00
//+------------------------------------------------------------------+
//| PRNG.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
#ifndef CRYPTOBYLEO_SRC_URANDOM_PRNG_MQH
#define CRYPTOBYLEO_SRC_URANDOM_PRNG_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <TSN\\Random\\Base.mqh>
#include "..\\Simetric\\AES\\Defines.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Interfaz base compatible con culquier bacjend de PRNGByLeo
// Esto no es seguro criptograficamente
// Igualemte se implementa dado que se quiere dar libertad a los usuarios si eleigr DLL o no
// Dado que en MQL5 no todos estan disepuestos a usar DLL en sus EAs
// Dado qeu conlleva ventjasa (seguridad en este caso) como desventjaas (dependeicneis si estas mas atado al ecosimta, tipo vender en market, o codebase)
// Por esa razon tambien se deja escojer una version nativa que usa PRNGByLeo por detras.. cieramnte no es seguro o comparble con urandom nativoi
// pero si no peudes usar dll almenos usa esto a usar directamnete el generador "pelado"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TBackend>
class CURandomPRNG
{
public:
CURandomPRNG(void) {}
~CURandomPRNG(void) {}
//---
static CRandom<TBackend> s_rand;
//--- Random crypto
2026-09-02 10:54:31 -05:00
static void RandomCryptoBytes(uchar& out[], int oult, int o_s = 0);
2026-09-01 12:16:15 -05:00
//--- Proposito general big integers
2026-09-01 12:25:55 -05:00
static void RandomUlongArr(ulong& out[], int oult, int o_s = 0);
static void RandomUlongArrRange(ulong& out[], int oult, ulong last, int o_s = 0);
2026-09-01 12:16:15 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TBackend>
CRandom<TBackend> CURandomPRNG::s_rand;
2026-09-01 12:16:15 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TBackend>
static void CURandomPRNG::RandomCryptoBytes(uchar& out[], int oult, int o_s = 0)
{
oult += o_s;
for(; o_s + 7 < oult;)
{
ulong ul = 0;
const ulong s = s_rand.nextUInt64();
switch(uchar(s & 7)) // % 8 = & 7
{
// fuentes de "entropia"
// ping_last, memory used (current), terminal retramsicion de paquetes
case 0:
{
ul = s_rand.nextUInt64();
break;
}
case 1:
{
ul = (ulong)TerminalInfoInteger(TERMINAL_PING_LAST) << 16;
break;
}
case 2:
{
ul = (ulong)TerminalInfoInteger(TERMINAL_MEMORY_USED) << 16;
break;
}
case 3:
{
ul = ulong(TerminalInfoDouble(TERMINAL_RETRANSMISSION) * 100) << 16;
break;
}
case 4:
{
ul = GetMicrosecondCount();
break;
}
case 5:
{
ul = GetTickCount64();
break;
}
case 6:
{
ul = ulong(SymbolInfoDouble(_Symbol, SYMBOL_BID) * SymbolInfoDouble(_Symbol, SYMBOL_LAST));
break;
}
case 7:
{
ul = (s_rand.nextUInt64() ^ s_rand.nextUInt64()) << (s_rand.nextUInt64() & 31);
break;
}
default:
break;
}
//--
if((s << 16) > 0)
{
ul = (ul << 32) | (ul >> 32);
}
//---
const ulong t = s_rand.nextUInt64();
out[o_s++] = g_aes_sbox[uchar(ul) ^ uchar(t)];
out[o_s++] = g_aes_sbox[uchar(ul >> 8) ^ uchar(t >> 8)];
out[o_s++] = g_aes_sbox[uchar(ul >> 16) ^ uchar(t >> 16)];
out[o_s++] = g_aes_sbox[uchar(ul >> 24) ^ uchar(t >> 24)];
out[o_s++] = g_aes_sbox[uchar(ul >> 32) ^ uchar(t >> 32)];
out[o_s++] = g_aes_sbox[uchar(ul >> 40) ^ uchar(t >> 40)];
out[o_s++] = g_aes_sbox[uchar(ul >> 48) ^ uchar(t >> 48)];
out[o_s++] = g_aes_sbox[uchar(ul >> 56) ^ uchar(t >> 56)];
}
//---
for(; o_s < oult; o_s++)
{
out[o_s] = g_aes_sbox[s_rand.nextUInt32() & 255];
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TBackend>
2026-09-01 12:25:55 -05:00
static void CURandomPRNG::RandomUlongArr(ulong& out[], int oult, int o_s = 0)
2026-09-01 12:16:15 -05:00
{
for(; o_s < oult; o_s++)
{
out[o_s] = s_rand.nextUInt64();
}
}
//+------------------------------------------------------------------+
template <typename TBackend>
2026-09-01 12:25:55 -05:00
static void CURandomPRNG::RandomUlongArrRange(ulong& out[], int oult, ulong last, int o_s = 0)
2026-09-01 12:16:15 -05:00
{
// completos
for(; o_s < oult - 1; o_s++)
{
out[o_s] = s_rand.nextUInt64();
}
//resto
out[o_s] = s_rand.boundedUInt64(last);
}
//---
}
#endif // CRYPTOBYLEO_SRC_URANDOM_PRNGHELP_BASE_MQH
//+------------------------------------------------------------------+