1
votes

I wanted to fill a std::vector<BYTE> with random or pseudo-random bytes of data. I have written (in other word, find it) the following source code in the stackoverflow but it doesn't compile in my Visual Studio.

#include <Windows.h>
#include <vector>
#include <random>
#include <climits>
#include <algorithm>
#include <functional>

using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, BYTE>;

int main()
{
    random_bytes_engine rbe;
    std::vector<BYTE> data(1000);
    std::generate(data.begin(), data.end(), std::ref(rbe));
}

When I try to compile the above code Visual studio give me the following errors:

Error C2338 note: char, signed char, unsigned char, char8_t, int8_t, and uint8_t are not allowed Messaging

Error C2338 invalid template argument for independent_bits_engine: N4659 29.6.1.1 [rand.req.genl]/1f requires one of unsigned short, unsigned int, unsigned long, or unsigned long long Messaging.

3

3 Answers

3
votes

The BYTE type, which is just an alias for unsigned char, is not an allowed type for UIntType parameter of

template<class Engine, std::size_t W, class UIntType>
class independent_bits_engine;

The standard, [rand.req.genl]/1.f, reads:

Throughout this subclause [rand], the effect of instantiating a template:

...

  • that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long.
2
votes

The answer from Evg is correct.

If you really want to have random bytes only, I would use a custom generator function that generates values between [-128, 127] or any desired range. For instance:

#include <iostream>
#include <Windows.h>

#include <vector>
#include <random>
#include <algorithm>
#include <limits>

int main()
{
    std::random_device r;
    std::default_random_engine randomEngine(r());
    std::uniform_int_distribution<int> uniformDist(CHAR_MIN, CHAR_MAX);

    std::vector<BYTE> data(1000);
    std::generate(data.begin(), data.end(), [&uniformDist, &randomEngine] () {
        return uniformDist(randomEngine);

    });

    for (auto i : data) {
        std::cout << int(i) << std::endl;
    }
    return 0;
}

References:

  1. https://en.cppreference.com/w/cpp/numeric/random
  2. https://en.cppreference.com/w/cpp/algorithm/generate
2
votes

Just do this instead:

using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, 32, uint32_t>;

Turns the engine into a 32-bit random number generator, but using it to initialize a vector of BYTEs works just fine.