繁体   English   中英

如何使用C / C ++预处理器生成一系列随机数

[英]How to generate a series of random numbers with the C/C++ preprocessor

我想用C预处理器生成一系列随机数,并将它们存储在变量中供我的程序使用。

目的:

我想在每次构建程序时生成一组“唯一”的随机数。 存储随机数的变量的一小部分将被有意义的(即非随机的)数字覆盖。 我希望黑客不可能通过调试程序或比较多个构建来区分有意义的数字和随机数。 我希望构建过程自动化并且自包含。 我希望实现可以跨Visual Studio和GCC移植。

澄清:

  1. 计算必须在编译时完成,而不是在程序执行时完成。 调试程序的任何人都应该只能看到,例如,一个变量被初始化为一个常量(随机数)。
  2. 随机数应该是整数。
  3. 随机数生成器应以某种方式从__DATE____TIME__ __DATE__ ,这样不同的构建将产生不同的随机数。
  4. 能够指定随机数的范围(例如从1到100)将是优选的,但不是绝对必要的。
  5. 能够指定要生成的随机数的总数(例如,声明1000个变量并将每个变量初始化为随机数)将是优选的,但不是绝对必要的。

到目前为止:

  1. 预处理器中关于算术的先前线程: C预处理器可以执行整数运算吗? 外卖是#if条件可以评估算术。
  2. 谷歌搜索显示除了算术,移位和位操作也可以由#if评估。 我已经使用Visual Studio C ++确认了这一点。
  3. 简单随机数发生器的候选者: http//www.ciphersbyritter.com/NEWS4/RANDC.HTM#369B5E30.65A55FD1@stat.fsu.edu这些发生器中的任何一个,或任何不能从给定的逆向工程中生成的发生器一系列随机数,没问题,因为我不需要特别好的发电机。 为了本练习,我们可以使用以下示例:

     unsigned long jcong=380116160; #define CONG (jcong=69069*jcong+1234567) 
  4. 我认为基本问题是在连续调用生成器之间存在存储在变量jcong中的状态。 据我所知,预处理器不支持变量赋值。 也许有一些聪明的递归宏可以做到这一点?

  5. 我能得到的最接近但不满足预处理器执行的目标是:

     unsigned long jcong=380116160; unsigned long randomBlock[] = {jcong=69069*jcong+1234567, jcong=69069*jcong+1234567}; 

    我已经在Visual Studio C ++中确认这确实将数组成员初始化为不同的随机数。 但是,调试器仍然会逐步完成初始化。

这是一个纯粹的编程/实现问题,所以请不要改变预处理器的邪恶或打击黑客的徒劳。

所以,这是接近要求的解决方案:

// pprand.h

#include <boost/preprocessor/slot.hpp>

#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 <stdio.h>

template <int N>
struct Random {
    enum { value = 7 * Random<N-1>::value + 17 };
};

template <>
struct Random<1> {
    enum { value = SEED};
};

template <int N, int BEG, int END>
struct RandomIn {
    enum { value = BEG + Random<N>::value % (END-BEG) };
};

int main() {
    printf("%d %d", RandomIn<2, 5, 10>::value, RandomIn<3, 5, 10>::value);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM