如何使用C / C ++预处理器生成一系列随机数
我想用C预处理器生成一系列随机数,并将它们存储在变量中供我的程序使用。
目的:
我想在每次构建程序时生成一组“唯一”的随机数。 存储随机数的一小部分变量将被有意义的(即非随机的)数字覆盖。 我希望黑客不可能通过调试程序或比较多个构建来区分有意义的数字和随机数。 我希望构建过程自动化并且自包含。 我希望实现可以跨Visual Studio和GCC移植。
澄清:
- 计算必须在编译时完成,而不是在程序执行时完成。 调试程序的任何人都应该只能看到,例如,一个变量被初始化为一个常量(随机数)。
- 随机数应该是整数。
- 随机数生成器应以某种方式从
__DATE__
和__TIME__
__DATE__
,这样不同的构建将产生不同的随机数。 - 能够指定随机数的范围(例如从1到100)将是优选的,但不是绝对必要的。
- 能够指定要生成的随机数的总数(例如,声明1000个变量并将每个变量初始化为随机数)将是优选的,但不是绝对必要的。
到此为止:
- 预处理器中的先前运算线程: C预处理器可以执行整数运算吗? 外卖是#if条件可以评估算术。
- 谷歌搜索显示除了算术,移位和位操作也可以由#if评估。 我已经使用Visual Studio C ++确认了这一点。
-
简单随机数发生器的候选人: http : //www.ciphersbyritter.com/NEWS4/RANDC.HTM#369B5E30.65A55FD1@stat.fsu.edu这些发生器中的任何一个,或任何不能从给定的逆向工程的发电机一系列随机数,没问题,因为我不需要特别好的发电机。 为了本练习,我们可以使用以下示例:
unsigned long jcong=380116160; #define CONG (jcong=69069*jcong+1234567)
-
我认为基本问题是在连续调用生成器之间存在存储在变量jcong中的状态。 据我所知,预处理器不支持变量赋值。 也许有一些聪明的递归宏可以做到这一点?
-
我能得到的最接近但不满足预处理器执行的目标是:
unsigned long jcong=380116160; unsigned long randomBlock[] = {jcong=69069*jcong+1234567, jcong=69069*jcong+1234567};
我已经在Visual Studio C ++中确认这确实将数组成员初始化为不同的随机数。 但是,调试器仍然会逐步完成初始化。
这是一个纯粹的编程/实现问题,所以请不要对预处理器的邪恶或黑客打击的无用性进行改编。
所以,这是接近要求的解决方案:
// pprand.h #include #ifndef PP_RAND_SEED #define PP_RAND_SEED (((PP_RAND_MIN + PP_RAND_MAX) * 0x1f7) ^ 0x1e3f75a9) #endif #define BOOST_PP_VALUE ((PP_RAND_SEED * 214013 + 2531011) % 65536) #include BOOST_PP_ASSIGN_SLOT(1) #undef BOOST_PP_VALUE #undef PP_RAND_SEED #define PP_RAND_SEED BOOST_PP_SLOT(1) #define BOOST_PP_VALUE (PP_RAND_MIN + PP_RAND_SEED % (PP_RAND_MAX - PP_RAND_MIN)) #include BOOST_PP_ASSIGN_SLOT(2) #undef BOOST_PP_VALUE #ifdef PP_RAND #undef PP_RAND #endif #define PP_RAND BOOST_PP_SLOT(2)
你可以像这样使用它:
// Pseudo random number range. #define PP_RAND_MIN 0 #define PP_RAND_MAX 100 // Pseudo random number seed. #define PP_RAND_SEED 123 #include "pprand.h" // Got it! #pragma message("PP_RAND value:" _CRT_STRINGIZE(PP_RAND))
要了解有关此方法的更多信息,请访问我的博客: http : //alexander-stoyan.blogspot.com/2012/07/getting-pseudo-random-numbers-at.html
您必须将Random generator序列替换为实际生成可接受的半随机值的内容,但该部分应该很容易。
您必须在编译时使用-DSEED=...
定义随机种子。 不知道如何使用__TIME__
和__DATE__
来做到这一点,因为它们是字符串。
#include template struct Random { enum { value = 7 * Random::value + 17 }; }; template <> struct Random<1> { enum { value = SEED}; }; template struct RandomIn { enum { value = BEG + Random::value % (END-BEG) }; }; int main() { printf("%d %d", RandomIn<2, 5, 10>::value, RandomIn<3, 5, 10>::value); return 0; }