I would like to generate a series of random numbers with the C preprocessor, and store them in variables for use by my program.
OBJECTIVES:
I would like to generate a "unique" set of random numbers every time I build my program. A small subset of the variables storing the random numbers will be overwritten with meaningful (ie non-random) numbers. I would like it to be impossible for a hacker, by debugging the program or comparing multiple builds, to be able to differentiate the meaningful numbers from the random numbers. I would like the build process to be automated and self-contained. I would like the implementation to be portable across Visual Studio and GCC.
CLARIFICATIONS:
__DATE__
and __TIME__
, so that different builds will yield different random numbers. ATTEMPTS SO FAR:
Candidates for simple random number generators: http://www.ciphersbyritter.com/NEWS4/RANDC.HTM#369B5E30.65A55FD1@stat.fsu.edu Any one of these generators, or any generator that is impossible to reverse engineer from a given series of random numbers, would be fine because I don't need a particularly well behaved generator. For the sake of this exercise, we can use the following as an example:
unsigned long jcong=380116160; #define CONG (jcong=69069*jcong+1234567)
I think the basic problem is that there is state that is stored in the variable jcong between successive calls to the generator. Variable assignment is not supported in the preprocessor, as far as I know. Perhaps there is some clever recursive macro that can do the trick?
The closest I could get, but not satisfying my objective of being performed by the preprocessor, is:
unsigned long jcong=380116160; unsigned long randomBlock[] = {jcong=69069*jcong+1234567, jcong=69069*jcong+1234567};
I have confirmed in Visual Studio C++ that this does indeed initialize the array members to different random numbers. However, the debugger still steps through the initialization.
This is a pure programming/implementation question, so please, no proselytizing on the evils of the preprocessor or the futility of fighting hackers.
So, here is the solution that is close to requirements:
// 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)
You can use it like this:
// 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))
To read more about this approach visit my blog: http://alexander-stoyan.blogspot.com/2012/07/getting-pseudo-random-numbers-at.html
You have to replace the Random generator sequence with something that actually generates acceptable semi-random values, but that part should be easy.
You have to define a random seed with -DSEED=...
at compilation. No idea how to do that with __TIME__
and __DATE__
because they are strings.
#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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.