I've written a funtion to prouduce random bytes in a uint8_t
type array, unless I seed this with a random_device
object it works fine but when I seed there are some compiler errors.
code:
#include <algorithm>
#include <random>
#include <functional>
#include <stdint>
void generateInitVector(uint8_t IV_buff[16])
{
using bytes_randomizer = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
std::random_device rd;
bytes_randomizer bytes(rd);
std::generate(std::begin(IV_buff), std::end(IV_buff), std::ref(bytes));
}
compiler errors:
1. error: no matching function for call to 'begin(uint8_t*&)'|
2. error: request for member 'begin' in '__cont', which is of non-class type 'unsigned char*'|
3. error: request for member 'begin' in '__cont', which is of non-class type 'unsigned char* const'|
4. error: no matching function for call to 'end(uint8_t*&)'|
5. error: request for member 'begin' in '__cont', which is of non-class type 'unsigned char*'|
6. error: request for member 'end' in '__cont', which is of non-class type 'unsigned char* const'|
7. error: 'class std::random_device' has no member named 'generate'|
There's catch that if I define a uint8_t
type array within th function
uint8_t data[16];
std::generate(std::begin(data), std::end(data), std::ref(bytes)); //and pass this array in `generate()`.
then only error 7 remains. Any solutions to this?
The issue here is that even though your function looks like
void generateInitVector(uint8_t IV_buff[16])
What it really is, thanks to the array decaying into a pointer is
void generateInitVector(uint8_t * IV_buff)
So, because you have a pointer, you cannot use std::begin
and std::end
. What you need to do is pass the array by reference to keep it an array. That looks like
void generateInitVector(uint8_t (&IV_buff)[16])
and now you can use std::begin
and std::end
and you maintain the size information of the array. You can even make it generic for the size using a template like
template<std::size_t N>
void generateInitVector(uint8_t (&IV_buff)[N])
{
using bytes_randomizer = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
std::random_device rd;
bytes_randomizer bytes(rd);
std::generate(std::begin(IV_buff), std::end(IV_buff), std::ref(bytes));
}
You also have an issue with
bytes_randomizer bytes(rd);
std::independent_bits_engine
expects a PRNG of the type of the first template parameter. You used std::default_random_engine
which is not the same as std::random_device
. You will need to change one of them to match the other in order for it to compile. For example:
template<std::size_t N>
void generateInitVector(uint8_t (&IV_buff)[N])
{
using bytes_randomizer = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
std::default_random_engine rd;
bytes_randomizer bytes(rd);
std::generate(std::begin(IV_buff), std::end(IV_buff), std::ref(bytes));
}
int main()
{
uint8_t data[16];
generateInitVector(data);
}