用随机字节填充字节向量
Posted
技术标签:
【中文标题】用随机字节填充字节向量【英文标题】:Filling a vector of bytes with random bytes 【发布时间】:2021-01-17 09:14:19 【问题描述】:我想用随机或伪随机字节的数据填充std::vector<BYTE>
。我已经在 *** 中编写(换句话说,找到它)以下源代码,但它没有在我的 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));
当我尝试编译上述代码时,Visual Studio 给我以下错误:
错误 C2338 注意:char、signed char、unsigned char、char8_t、int8_t、 和 uint8_t 不允许消息传递
Independent_bits_engine 的错误 C2338 模板参数无效: N4659 29.6.1.1 [rand.req.genl]/1f 需要 unsigned short 之一, unsigned int、unsigned long 或 unsigned long long 消息传递。
【问题讨论】:
【参考方案1】:BYTE
类型,它只是 unsigned char
的别名,不是 UIntType
参数的允许类型
template<class Engine, std::size_t W, class UIntType>
class independent_bits_engine;
标准,[rand.req.genl]/1.f,reads:
在整个子条款 [rand] 中,实例化模板的效果:
...
具有名为UIntType
的模板类型参数是未定义的,除非相应的模板参数是 cv-unqualified 并且是unsigned short
、unsigned int
、unsigned long
或unsigned long long
之一。
【讨论】:
【参考方案2】:Evg 的回答是正确的。
如果你真的只想有随机字节,我会使用自定义生成器函数来生成 [-128, 127] 或任何所需范围之间的值。 例如:
#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;
参考资料:
-
https://en.cppreference.com/w/cpp/numeric/random
https://en.cppreference.com/w/cpp/algorithm/generate
【讨论】:
std::numeric_limits<BYTE>::min(), std::numeric_limits<BYTE>::max()
会更清晰。
我最初确实使用过它们,但不知何故它没有与 msvc 19.20(在 godbolt.org 上)一起编译。这就是为什么我将答案恢复为 CHAR_MIN / CHAR_MAX。
@Anton 这是 MSVC 中的一个已知问题。只需在包含Windows.h
之前定义NOMINMAX
宏。 example - 如果您使用C
宏,请使用(0, UCHAR_MAX)
而不是(CHAR_MIN, CHAR_MAX)
,并且分发最好使用unsigned
类型。
谢谢!我不知道。 11 年前我还没有在 Windows 上用 C++ 编程过。
最近我一直在初始化生成器 lambda 捕获列表中的随机生成器和分布,以保持我的范围干净(在其他任何地方都不需要)。不过需要 C++17。例如。 [uniformDist = std::uniform_int_distribution(std::numeric_limits<BYTE>::min(), std::numeric_limits<BYTE>::max()), randomEngine = std::default_random_enginestd::random_device()] () mutable return uniformDist(randomEngine);
【参考方案3】:
只需这样做:
using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, 32, uint32_t>;
将引擎变成 32 位随机数生成器,但使用它来初始化 BYTE 向量就可以了。
【讨论】:
以上是关于用随机字节填充字节向量的主要内容,如果未能解决你的问题,请参考以下文章