我正在处理std::bitset<16>
向量中的数据,我必须使用自制函数将无符号长(通过std::bitset::to_ulong()
)和来自字符串的字符串进行转换(精确算法对于这个问题是无关紧要的)
bitset vector和string之间的转换起初似乎工作正常,因为如果我首先将bitsets的向量转换为string然后再转换为bitset它是相同的;我通过制作一个包含这个的程序证明了这一点:
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
首先很明显,当显示为二进制时,仍然超出所有合理怀疑的位集是相同的,但是当转换为无符号长整数时,相同的位集返回完全不同的值(完全毁了我的程序)
这是为什么?即使它们的打印方式相同,它们是不一致的吗?虽然位集相同,但我的bitset中是否存在错误存在于字符串转换器中?
编辑:并非包括我的对话在内的所有程序都有这个问题,只有在我创建它(从字符串)后修改了bitset时才会发生这种情况,在我的情况下尝试加密bitset,这根本无法切割简单而简短,但在我最压缩的写作方式中,它看起来像这样:
(甚至没有包括公钥结构和模块化功能函数的定义)
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; s和0&#39; s)转换为相同的无符号长整数。
其他编辑:我还必须指出,unsigned longs的第一个printet值是&#34;正确&#34;因为它们在使用时允许我完美地解密bitset,而之后打印的unsigned longs的值是&#34;错误&#34;因为它会产生完全错误的结果。
答案 0 :(得分:2)
“11841744”值在低16位中是正确的,但在16位之上有一些额外的设置位。这可能是您的STL实现中的一个错误,其中to_long访问它应该使用的16位之后的位。
或者(从上面的评论中)你为bitset添加的位数多于它可以容纳的位数,并且你遇到了未定义的行为。