如何将 bitset 转换为 bytes/uint8 数组?

Posted

技术标签:

【中文标题】如何将 bitset 转换为 bytes/uint8 数组?【英文标题】:How do I convert bitset to array of bytes/uint8? 【发布时间】:2012-01-08 00:49:24 【问题描述】:

我需要从可能(不)包含多个 CHAR_BIT 位的位集中提取字节。我现在需要将位集中的多少位放入数组中。例如,

位组声明为std::bitset < 40> id;

有一个单独的变量nBitsid 中有多少位可用。现在我想以 CHAR_BIT 的倍数提取这些位。我还需要处理nBits % CHAR_BIT != 0 的情况。我可以把它放到一个 uint8 数组中

【问题讨论】:

苛刻...如果您的位数小于 sizeof(unsigned long) 位,则使用bitset::to_ulong 会很简单。事实上,我认为没有简单的解决方案。 std::bitset 没有 data()std::vector 那样的东西(尽管 gcc 版本有一个未记录和实验性的 _M_getdata 函数,就是这样......)`。由于没有其他东西,您只能单独访问各个位。或者,序列化为字符串或通过流进行,但这些都不是特别有效。 【参考方案1】:

不幸的是,语言中没有好的方法,假设您需要的位数超过 unsigned long 中的位数(在这种情况下,您可以使用 to_ulong)。您必须遍历所有位并自己生成字节数组。

【讨论】:

【参考方案2】:

您可以使用boost::dynamic_bitset,使用boost::to_block_range可以将其转换为“块”范围。

#include <cstdlib>
#include <cstdint>
#include <iterator>
#include <vector>
#include <boost/dynamic_bitset.hpp>

int main()

    typedef uint8_t Block; // Make the block size one byte
    typedef boost::dynamic_bitset<Block> Bitset;

    Bitset bitset(40); // 40 bits

    // Assign random bits
    for (int i=0; i<40; ++i)
    
        bitset[i] = std::rand() % 2;
    

    // Copy bytes to buffer
    std::vector<Block> bytes;
    boost::to_block_range(bitset, std::back_inserter(bytes));

【讨论】:

需要注意的一个问题是向量的内部类型需要匹配用于构造位集的块类型(在本例中为unsigned char)。如果 bitset 有 4 字节的块,但向量有 1 字节的块,to_block 将默默地切掉每个块的后 3 个字节。因此,将 Emile 的回答中的向量声明更改为 std::vector&lt;Bitset::Block&gt; bytes 会更安全一些。 更正我的评论:内部类型是Bitset::block_type,而不是Bitset::Block @prideout:添加Block typedef 以避免您描述的情况。【参考方案3】:

使用标准 C++11,您可以通过移位和屏蔽从 40 位 bitset 中获取字节。我没有处理不同的值而不是 8 和 40 以及当第二个数字不是第一个数字的倍数时的处理。

#include <bitset>
#include <iostream>
#include <cstdint>

int main() 
    constexpr int numBits = 40;

    std::bitset<numBits> foo(0x1234567890);
    std::bitset<numBits> mask(0xff);

    for (int i = 0; i < numBits / 8; ++i) 
        auto byte =
            static_cast<uint8_t>(((foo >> (8 * i)) & mask).to_ulong());
        std::cout << std::hex << setfill('0') << setw(2) << static_cast<int>(byte) << std::endl;
    

【讨论】:

以上是关于如何将 bitset 转换为 bytes/uint8 数组?的主要内容,如果未能解决你的问题,请参考以下文章

在Swift中将bytes / UInt8数组转换为Int

如何将任何用户定义的类型转换为 std::bitset?

如何将 C++ 位集中的位范围子集转换为数字? [复制]

在 C++ 中将 bitset 转换为 int

是否可以在 C++ 中将 bitset<8> 转换为 char?

从 BitSet 转换为 Byte 数组