用随机字节填充字节向量

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 shortunsigned intunsigned longunsigned 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&lt;BYTE&gt;::min(), std::numeric_limits&lt;BYTE&gt;::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&lt;BYTE&gt;::min(), std::numeric_limits&lt;BYTE&gt;::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 向量就可以了。

【讨论】:

以上是关于用随机字节填充字节向量的主要内容,如果未能解决你的问题,请参考以下文章

用向量中的随机值填充数据框中的 NA 值(无需替换)

在 C# 中使用线程填充随机数的数组

用随机名称填充的字符串数组

我可以创建一个用六个随机数填充 100 个数组的循环吗?

我该如何生成初始化向量?

将随机数存储在字节数组中