如何在C++中从8位(uint8_t)数组获得11位表示

jdzmm42g  于 2023-05-02  发布在  其他
关注(0)|答案(2)|浏览(194)

我正在尝试在我的项目中实现BIP 39标准。其他一切都很好,但我被严重卡住了,我已经搜索了谷歌和ChatGPT的最大深度,但没有找到解决方案。
我有一个向量<uint8_t>,它存储了33字节的熵和校验和。
vector <uint8_t> ent_cs; //have already put 256 bits (32 bytes) of entropy and 8 bits (1 byte) checksum
我试图将这个数组读取为vector <uint16_t>中的11位表示(0 - 2,047),这样我就可以为每个数字分配一个助记词,这些数字将用作种子来生成私钥。
C++也没有原生的11位整数数据类型
谢谢
我期待24个11位数字,在0和2047之间,存储在uint16_t数组/向量中

bq3bfh9z

bq3bfh9z1#

这里有一些简单的代码,它的目的是为了便于理解,而不是最终的效率

// 33 bytes is 24 11-bit numbers
for (size_t i = 0; i < 24; ++i)
{
    size_t offset = 11*i;
    size_t byte_offset = offset/8;
    unsigned bit_offset = offset%8;
    unsigned number = 0;
    size_t bits_copied = 0;
    if (bit_offset != 0)
    {
        // extract high bits from the first byte
        number += ent_cs[byte_offset] >> bit_offset;
        bits_copied += 8 - bit_offset;
        ++byte_offset;
        bit_offset = 0;
    }
    while (bits_copied < 11)
    {
        // extract whole byte
        number += ent_cs[byte_offset] << bits_copied;
        bits_copied += 8;
        ++byte_offset;
    }
    // remove any overflow (since bits_copied maybe greater than 11)
    number &= (1 << 11) - 1;
    std::cout << number << '\n';
}

似乎起作用了。我做了一些假设,特别是向量中的低位和字节是11位数字中的低位。

pjngdqdw

pjngdqdw2#

进行这种转换的最简单方法是使用整数类型来缓冲输入中的位,只要积累足够就生成输出字。
从我找到的描述来看,BIP 39似乎想要一个big-endian转换,所以它看起来像这样:

std::vector<uint16_t> convert8sto11s(std::vector<uint8_t> &in) {
    uint32_t buf = 0;
    unsigned bits = 0;
    std::vector<uint16_t> out;
    for (uint8_t c : in) {
        buf = (buf<<8) | c;
        bits += 8;
        if (bits >= 11) {
            bits-=11;
            out.push_back((uint16_t)( (buf>>bits) & 2047 ));
        }
    }
    return out;
}

相关问题