[Development] websockets (was RE: Qt 5.3 Feature freeze is coming quite soon...)

Olivier Goffart olivier at woboq.com
Sun Feb 9 23:57:24 CET 2014


On Sunday 09 February 2014 22:40:22 Kurt Pattyn wrote:
> If I use std::random as Thiago proposed (see
> http://en.cppreference.com/w/cpp/numeric/random), like:
> 
>     //one time initialisation
>     Q_CONST_EXPR std::size_t numSeeds = 13;	//arbitrary number
>     quint32 seeds[numSeeds] = { 0 };
>     bool success = false;
> 
>     try {
>         std::random_device seeder;		//supported since MSVS 2008, since 
GCC
> 4.5 if (seeder.entropy() >= 0.5) {
>             std::generate_n(seeds, numSeeds, seeder);
>             success = true;
>         }
>     } catch (const std::exception &) {
>         //fall through
>     }
> #ifdef Q_OS_WIN  //the MinGW implementation of GCC 4.8 has a known bug in
> std::random_device if (!success) {
>         HCRYPTPROV hp = 0;
>         BYTE rb[4];
>         if ((success = CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL,
> CRYPT_VERIFYCONTEXT)) == TRUE) for (std::size_t i = 0; i < numSeeds; ++i) {
>                 if ((success = CryptGenRandom(hp, sizeof(quint32), seeds +
> i) != TRUE) break;
>         }
>         CryptReleaseContext(hp, 0);
>     }
> #endif
>     if (!success) {
>         qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
>         for (std::size_t i = 0; i < numSeeds; ++i) {
>             const qreal multiplier =
> qreal(std::numeric_limits<quint8>::max()) / qreal(RAND_MAX); const quint32
> byte1 = quint32(qrand() * multiplier) & 0xFF; const quint32 byte2 =
> quint32(qrand() * multiplier) & 0xFF; const quint32 byte3 = quint32(qrand()
> * multiplier) & 0xFF; const quint32 byte4 = quint32(qrand() * multiplier) &
> 0xFF; seeds[i] = byte1 | byte2 << 8 | byte3 << 16 | byte4 << 24; }
>     }
> 
>     std::seek_seq seedSequence(seeds, seeds + numSeeds);
>     std::mt19937 randomiser(seedSequence);
>     //std::uniform_int_distribution<std::uint32_t> dist;	//range from 0 to
> UINT_MAX
> 
> 
>     //somewhere else
>     return randomiser();	//no need to use a distribution function as mt19937
> outputs 2^32
> 
> 
> Would this already be more acceptable?
> Of course, this implementation requires C++11 support.
> An interesting presentation about std::random can be found here:
> http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
> 
> If the above implementation suffices, then a virtual method would not be
> needed anymore.
> 
> Should I fall back to the ordinary qrand() when the other methods fail?
> 

I think you are making it more complicated than it  need to be.
qrand has maximum 32bit entropy (because it uses rand_r internally which only 
has 32 bit state), therefore calling it several time in a row is totally 
useless and don't add entropy.
It turns out 32 bit entropy is enough because that's the size of your mask, so 
just use qrand with a decent proper seed:


#if has_std_randrom_device
return qsrand(std::random_device()());
#else
static QElapsedTimer t;
return qsrand(t.nsecsElapsed());
#endif

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org





More information about the Development mailing list