我正在处理std::bitset<16> vector 中的数据,我都必须使用自制函数将其与unsigned long(通过std::bitset::to_ulong())和字符串进行来回转换(确切的算法对此问题不适用)

比特集 vector 和字符串之间的转换起初看起来确实不错,因为如果我先将比特集的 vector 转换为字符串,然后再返回比特集,则它是相同的;我已通过编写包含以下内容的程序来证明这一点:

for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<std::endl;//print bitsets before conversion

bitset_to_string(my_bitset16vector,my_str);
string_to_bitset(my_bitset16vector,my_str);

std::cout<<std::endl
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<std::endl;//print bitsets after conversion

输出可能看起来像这样(在这种情况下只有4个位集):
1011000011010000
1001010000011011
1110100001101111
1001000011001111

1011000011010000
1001010000011011
1110100001101111
1001000011001111

以此判断,转换前后的位集显然是相同的,但是尽管如此,当我告诉它们转换为无符号长型时,位集的转换完全不同。在看起来像这样的程序中:
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<".to_ulong()="<<B.to_ulong()<<std::endl;//print bitsets before conversation

bitset_to_string(my_bitset16vector,my_str);
string_to_bitset(my_bitset16vector,my_str);

std::cout<<std::endl
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<".to_ulong()="<<B.to_ulong()<<std::endl;//print bitsets after conversion

输出可能看起来像这样:
1011000011010000.to_ulong()=11841744
1001010000011011.to_ulong()=1938459
1110100001101111.to_ulong()=22472815
1001000011001111.to_ulong()=18649295

1011000011010000.to_ulong()=45264
1001010000011011.to_ulong()=37915
1110100001101111.to_ulong()=59503
1001000011001111.to_ulong()=37071

首先,很明显,在以二进制形式显示时,仍然毫无疑问的位集是相同的,但是当转换为无符号长整数时,相同的位集返回完全不同的值(完全破坏了我的程序)

为什么是这样?即使它们打印的相同,这些位集也可能不相同吗?尽管位组的相同,但我的位集与字符串转换器之间是否存在错误?

编辑:并非所有程序,包括我的对话都存在此问题,仅当我在创建位集(从字符串中)后修改了位集时才会发生这种情况,在本例中,是试图对位集进行加密,而该位集根本无法缩减为某种形式简单而简短,但是以我最压缩的书写方式,它看起来像这样:

(这甚至不包括公共(public)密钥结构和模块化幂函数的定义)
int main(int argc, char**argv)
{
    if (argc != 3)
    {
        std::cout<<"only 2 arguments allowed: plaintext user"<<std::endl;
        return 1;
    }

    unsigned long k=123456789;//any huge number loaded from an external file
    unsigned long m=123456789;//any huge number loaded from an external file


    std::vector< std::bitset<16> > data;
    std::string datastring=std::string(argv[1]);

    string_to_bitset(data,datastring);//string_to_bitset and bitset_to_string also empties string and bitset vector, this is not the cause of the problem

    for (std::bitset<16>& C : data)
    {
        C =std::bitset<16>(modpow(C.to_ulong(),k,m));//repeated squaring to solve C.to_ulong()^k%m
    }

    //and now the problem happens


    for (std::bitset<16>& C : data) std::cout<<C<<".to_ulong()="<<C.to_ullong()<<std::endl;

    std::cout<<std::endl;

    bitset_to_string(data,datastring);
    string_to_bitset(data,datastring);
    //bitset_to_string(data,datastring);

    for (std::bitset<16>& C : data) std::cout<<C<<".to_ulong()="<<C.to_ullong()<<std::endl;

    std::cout<<std::endl;
return 0;
}

我很清楚,大家现在都在考虑我做错了模块化幂函数(我保证我没有做错),但是我为实现这一目标所做的事情实际上并不重要,因为我的问题不是:我的程序有什么问题;我的问题是:为什么不将相同的位集(打印相同的二进制1和0)转换为相同的无符号长整型。

其他编辑:我还必须指出,无符号long的第一个printet值是“正确的”,因为使用它们时,我可以完美地解密位集,而随后打印的无符号long的值是“错误的”,因为它会产生一个完全错误的结果。

最佳答案

“11841744”值在较低的16位中是正确的,但在第16位以上具有一些额外的设置位。这可能是STL实现中的错误,其中to_long访问应使用的16位之后的位。

或者(从上面的评论中)您正在向位集中添加的位数超出了它可以容纳的位数,并且遇到了未定义行为。

关于c++ - 为什么不将相同的位集转换为相同的ulong,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40872815/

10-10 03:11