node-haystack Episode - 12 : A Better Random Generator
2016-09-19 05:53
423 查看
The built-in random generator of JavaScript does not look like so random. Anyway, even if there are so many random generator in js/C++/nodejs, I still decide to write my own one.
I found GNU org gives a lot of random generating algorithms(reference). I peeked the one of gls_rng_taus:
Generator: gsl_rng_taus
Generator: gsl_rng_taus2
It looks symmetric. I like it. And so on, here comes the C++ code:
And story goes on, now for node.js add-on:
And then the testing code:
According to a testing before, the duplication is about 0.2% when generating 10M random numbers. It’s good enough for our project. I plan to apply it for block’s cookie field. The cookie field exists for avoiding the attack by guessing the url. As same as the description of Facebook’s paper, an url like http://site.address/key/cookie will dramatically increase the difficulty of attacking.
I found GNU org gives a lot of random generating algorithms(reference). I peeked the one of gls_rng_taus:
Generator: gsl_rng_taus
Generator: gsl_rng_taus2
This is a maximally equidistributed combined Tausworthe generator by L’Ecuyer. The sequence is, x_n = (s1_n ^^ s2_n ^^ s3_n) where, s1_{n+1} = (((s1_n&4294967294)<<12)^^(((s1_n<<13)^^s1_n)>>19)) s2_{n+1} = (((s2_n&4294967288)<< 4)^^(((s2_n<< 2)^^s2_n)>>25)) s3_{n+1} = (((s3_n&4294967280)<<17)^^(((s3_n<< 3)^^s3_n)>>11)) computed modulo 2^32. In the formulas above ^^ denotes “exclusive-or”. Note that the algorithm relies on the properties of 32-bit unsigned integers and has been implemented using a bitmask of 0xFFFFFFFF to make it work on 64 bit machines. The period of this generator is 2^88 (about 10^26). It uses 3 words of state per generator. For more information see, P. L’Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. The generator gsl_rng_taus2 uses the same algorithm as gsl_rng_taus but with an improved seeding procedure described in the paper, P. L’Ecuyer, “Tables of Maximally Equidistributed Combined LFSR Generators”, Mathematics of Computation, 68, 225 (1999), 261–269 The generator gsl_rng_taus2 should now be used in preference to gsl_rng_taus.
It looks symmetric. I like it. And so on, here comes the C++ code:
/*! \brief Random number/uuid generator. */ class Random { public: Random(){ m_seed1 = std::time(nullptr); m_seed2 = std::time(nullptr); m_seed3 = std::time(nullptr); } Random(const Random&) = delete; /*! \brief Generate a random number in range of (0, 2^31] */ inline u32 Next() { m_seed1 = (((m_seed1 & 4294967294) << 12) ^ (((m_seed1 << 13) ^ m_seed1) >> 19)); m_seed2 = (((m_seed2 & 4294967288) << 4) ^ (((m_seed2 << 2) ^ m_seed2) >> 25)); m_seed3 = (((m_seed3 & 4294967280) << 17) ^ (((m_seed3 << 3) ^ m_seed3) >> 11)); return m_seed1 ^ m_seed2 ^ m_seed3; } /*! \brief Generate a random value in range of (0, rng]. */ inline u32 Next(u32 rng) { return ((u64)Next() * rng) / 0xFFFFFFFF; } private: u32 m_seed1; u32 m_seed2; u32 m_seed3; }; // class Random
And story goes on, now for node.js add-on:
class RandomObject : public NodeObjectTemplate<Random> { public: using self_t = RandomObject; using random_t = shared_t<wrapped_t>; public: explicit RandomObject(Random* rand):Base(rand) {} IMPL_INIT_FUNC("Random", { { "next", Next } }, { /* No props */ }) IMPL_NEW_FUNC(DEFAULT_NEW_FUNC()) private: ~RandomObject() { } /*! \brief Get a random value. \return unsigned 32 bits integer with no range specified; otherwise, return a random value in range of [0, specified rang). */ static void Next(const js_arg_t& args) { PREPARE_FUNC(args, 0, rand) u64 val = rand ? rand->Next() : 0; if (args.Length() > 0 && args[0]->IsNumber()) { val = (val * args[0]->Int32Value()) / 0xFFFFFFFF; } args.GetReturnValue().Set(static_cast<u32>(val)); } private: DECL_CTOR() }; // cls RandomObject
And then the testing code:
var rand = require('../node-random'); var i = 10240; var count = 0; while(i-- > 0) { if ( 100 === rand.next(100)) { count++; } } // while if (count > 0) { console.log('Getcha! ', count); } else { console.log('Not found'); }
According to a testing before, the duplication is about 0.2% when generating 10M random numbers. It’s good enough for our project. I plan to apply it for block’s cookie field. The cookie field exists for avoiding the attack by guessing the url. As same as the description of Facebook’s paper, an url like http://site.address/key/cookie will dramatically increase the difficulty of attacking.
相关文章推荐
- node-haystack Episode 12: problem of C++ closure
- node-haystack Episode 3: Callback model in C++
- node-haystack Episode 5: Volume
- node-haystack Episode 6: Data Structure And Constants
- node-haystack Episode 7: Asynchronously manipulate blocks
- node-haystack Episode 8: Simple Recovery And Verification
- node-haystack Episode 9: Manipulate Volume
- node-haystack Episode 1: What is it and why
- node-haystack Episode 2: Asynchronous and Threading
- node-haystack Episode 10: Node.js add-on
- node-haystack Episode 11: node object of Volume
- node-haystack Episode-4: Wrapper of libuv
- Python标准库12 数学与随机数 (math包,random包)
- cocos2d-x CCNode,CCLayer,CCScene分析-沈大海cocos2d-x教程12
- Linked List Random Node
- C++ 利用<cstdlib> 头文件 , 产生一个random number generator
- [转] A sample of Multiply-with-carry, a pseudo-random number generator
- Linked List Random Node
- When Does Deep Learning Work Better Than SVMs or Random Forests?
- 382. Linked List Random Node