2016-11-29 10 views
2

Я имею дело с данными в векторе std::bitset<16>, которые я должен преобразовать в unsigned long (через std::bitset::to_ulong()) и из строк с использованием самодельной функции (точный алгоритм является нерелятивным для этого вопроса)Почему не идентичные биты преобразуются в одинаковые ulong

Преобразования между вектором бит и строкой сначала кажутся прекрасными, так как это, если я сначала конвертирую вектор битов в строку, а затем обратно в биты, это идентично; которые я доказал, делая программу, которая включает в себя следующее:

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 bitsets):

1011000011010000 
1001010000011011 
1110100001101111 
1001000011001111 

1011000011010000 
1001010000011011 
1110100001101111 
1001000011001111 

Судя по этому, bitsets перед тем и после преобразования явно идентичны, однако, несмотря на это, биты преобразуются совершенно по-разному, когда я говорю им преобразовать в unsigned long; в программе, которая может выглядеть следующим образом:

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 

, во-первых, очевидно, что bitsets еще вне всякого разумного сомнения идентичны, когда отображаются в виде бинарный, но при преобразовании в unsigned long идентичные биты возвращают совершенно разные значения (полностью разрушая мою программу)

Почему t его? может быть, что биты неидентичны, хотя они печатаются одинаково? может ли ошибка существовать внутри моего битового набора в и из строковых преобразователей, несмотря на то, что биты идентичны?

Редактирование: не все программы, в том числе и мои разговоры, имеют эту проблему, это происходит только тогда, когда я изменил битрейт после его создания (из строки), в моем случае в попытке зашифровать битовый набор, который просто не может быть вырублено к чему-то простому и короткому, но в моей наиболее сжатой форме записи это выглядит следующим образом:

(и это даже без включения дефиниции ключа структуры и модульной функции общественного питания)

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; 
} 

Я хорошо знаю, что вы теперь все думаете, что я делаю модульную функцию власти неправильно (что я guara ntee, что я не), но то, что я делаю, чтобы это произошло, на самом деле не имеет значения, поскольку мой вопрос не был: что не так в моей программе; мой вопрос: почему не идентичные биты (которые печатают идентичные двоичные 1 и 0) конвертируются в одинаковые беззнаковые длинные.

Другое редактирование: я также должен указать, что первые значения печати беззнаковых длин являются «правильными», поскольку они при использовании позволяют мне отлично расшифровать битовый набор, тогда как значения беззнаковых длин, напечатанные впоследствии, являются «неправильными» в что он производит совершенно неправильный результат.

+0

Попробуйте извлечь наименьший фрагмент кода, который дублирует эту проблему (например, небольшую основную часть, которая показывает это). Мы не можем видеть примеры того, как вы назначаете свои данные в биты. –

+2

Какой компилятор вы используете? Значение «11841744» правильное в младших 16 бит, но имеет некоторые дополнительные биты набора выше 16-го. Это может быть ошибкой в ​​вашей реализации STL, где to_long обращается к битам за 16, которые он должен использовать. – 1201ProgramAlarm

+0

Оказывается, вы были правы @ 1201ProgramAlarm в моем случае 16 бит должны быть маленькими, чтобы содержать все данные, но мой компилятор все равно добавляет все данные в битрейт, обновление с 16 до 32 бит решает мою проблему; если бы вы могли опубликовать свой комментарий в качестве ответа, я приму его – Nikolaj

ответ

1

Значение «11841744» правильное в младших 16 бит, но имеет несколько дополнительных битов над шестнадцатым. Это может быть ошибкой в ​​вашей реализации STL, где to_long обращается к битам за 16, которые он должен использовать.

Или (из вашего комментария выше) вы добавляете больше битов в биты, чем может удерживать, и вы испытываете неопределенное поведение.