簡體   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