2011-06-27 21 views
3

Cプリプロセッサで一連の乱数を生成し、変数に格納してプログラムで使用したいと考えています。C/C++プリプロセッサで一連の乱数を生成する方法

目的:

私は私が私のプログラムをビルドするたびにランダムな数字の「ユニーク」セットを生成したいと思います。乱数を格納する変数の小さなサブセットは、意味のある(すなわち、非ランダムな)番号で上書きされる。意味のある数字と乱数を区別できるように、プログラムをデバッグしたり、複数のビルドを比較したりすることで、ハッカーにとって不可能であることを望みます。ビルドプロセスを自動化し、自立させたいと思います。実装をVisual StudioとGCCで移植可能にしたいと思います。

明確化:

  1. 計算がないプログラムの実行時に、コンパイル時に行われなければなりません。プログラムをデバッグする人は、変数が定数(乱数)に初期化されているかどうかだけを知ることができます。
  2. 乱数は整数でなければなりません。
  3. 乱数ジェネレータは、何らかの方法で__DATE____TIME__からシードされる必要があります。そのため、異なるビルドで異なる乱数が生成されます。
  4. 乱数の範囲(例えば、1から100)を指定できることが望ましいことは絶対に必要ではありません。
  5. 生成する乱数の総数を指定できる(たとえば、1000個の変数を宣言し、それぞれを乱数に初期化する)ことが可能であることが望ましい場合がありますが、絶対に必要なわけではありません。 SO FAR

の試み:プリプロセッサでの算術上の

  1. 前のスレッド:Can the C preprocessor perform integer arithmetic? 持ち帰りの#if条件が算術演算を評価することができるということです。
  2. グーグルでは、演算以外に、#ifによってシフト演算とビット演算も評価できることがわかります。 Visual Studio C++でこれを確認しました。
  3. 単純乱数発生器の候補:http://www.ciphersbyritter.com/NEWS4/RANDC.HTM#[email protected] 乱数発生器のいずれか1つ、または乱数発生器からリバースエンジニアリングすることが不可能な任意の発生器は、特にうまく動作するジェネレータ。この演習のために、私たちは一例として、以下を使用することができます。

    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++で確認しています数字。ただし、デバッガはまだ初期化を実行します。

これは純粋なプログラミング/実装上の問題、プリプロセッサやハッカーとの戦いの無益の悪にそうしてください、ノー布教です。

+0

本当にプリプロセッサかC++のtempが必要ですか遅いですか? –

+0

プリプロセッサは必須ではありません。私は実行可能ファイルを通して "unhackable"にするだけで十分です。 – Dale

+1

@Dale「私はそれだけで「解けない」ことが必要です」 - あなたには悪い知らせがありますが、それはうまくいかないでしょう。システムは破壊されません。 –

答えて

1

実際に許容されるセミランダム値を生成するものでランダム生成器シーケンスを置き換える必要がありますが、その部分は簡単にする必要があります。

コンパイル時に-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; 
} 
+0

これは良いことです。 Visual Studioでコードを検証しました。 – Dale

+0

変数の数を柔軟に設定する方法があるのでしょうか?今のように、各変数にRandomIn をハードコードする必要があります。 – Dale

+0

私はあなたの質問を理解していません。それは、各Nのための異なる確率変数を作成します。100が必要な場合は、100の異なるN - sを使用してください。 –

3

、ここでは要件に近い解である:

// 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

+0

あなたの答えを投稿してくれてありがとう! [自己プロモーションに関するよくある質問](http://stackoverflow.com/faq#promotion)をよく読んでください。また、自分のサイト/製品にリンクするたびに免責条項を掲示することが必須*であることにも注意してください。私はあなたに必要な免責事項を編集中です。 –

関連する問題