2013-11-21 8 views
0

может кто-нибудь объяснить, что делает этот код? я должен интерпретировать этот код и использовать его в качестве кода контрольной суммы, но я не уверен, что это абсолютно правильно. Особенно, как работают переливы и что означает *cp, const char* cp и sum & 0xFFFF? Основная идея заключалась в том, чтобы взять ввод как строку от пользователя, преобразовать его в двоичную форму по 16 бит за раз. Затем суммируйте все 16 бит вместе (в двоичном формате) и получите 16-разрядную сумму. Если в добавлении есть бит переполнения, добавьте это к lsb окончательной суммы. Затем возьмите дополнение к результату.код контрольной суммы в C++

Насколько близок этот код к выполнению вышеуказанного?

unsigned int packet::calculateChecksum() 

{ 
unsigned int c = 0; 
int i; 
string j; 
int k; 
cout<< "enter a message" << message; 
getline(cin, message) ; // Some string. 
//std::string message = 
std::vector<uint16_t> bitvec; 
const char* cp = message.c_str()+1; 
while (*cp) { 
    uint16_t bits = *(cp-1)>>8 + *(cp); 
    bitvec.push_back(bits); 
    cp += 2; 
} 

uint32_t sum=0; 
uint16_t overflow=0; 
uint32_t finalsum =0; 

// Compute the sum. Let overflows accumulate in upper 16 bits. 
for(auto j = bitvec.begin(); j != bitvec.end(); ++j) 
    sum += *j; 

// Now fold the overflows into the lower 16 bits. Loop until no overflows. 
do { 
    sum = (sum & 0xFFFF) + (sum >> 16); 
    } while (sum > 0xFFFF); 

// Return the 1s complement sum in finalsum 
finalsum = 0xFFFF & sum; 

    //cout<< "the finalsum is" << c; 
     c = finalsum; 
     return c; 

    } 
+1

По крайней мере, его дополнение должно быть либо 0xFFFF^sum, либо 0xFFFF - sum: цикл 'while (* cp)' неверен, так как он не может корректно обрабатывать например строка "a". (Что, если есть мусор сразу после завершающего ascii нуля? –

+0

Есть ли причина против использования стандартного хеш-кода, такого как SHA (http://en.wikipedia.org/wiki/Secure_Hash_Algorithm)? –

+0

BTW. Этот тип Q принадлежит codeview. –

ответ

0

Я вижу несколько проблем в коде:

  1. cp является указателем на ноль закончился массив символов, удерживающий сообщение ввода. У while(*cp) будет проблема, так как внутри тела цикла while cp увеличивается на 2 !!! Поэтому довольно легко пропустить окончание \0 массива символов (например, входное сообщение имеет 2 символа) и привести к ошибке сегментации.
  2. *(cp) и *(cp-1) введите два соседних символа (байты) во входном сообщении. Но почему двухбайтовое слово формируется *(cp-1)>>8 + *(cp)? Я думаю, было бы разумно сформировать 16-битное слово на *(cp-1)<<8 + *(cp), то есть предыдущий символ сидит на более высоком байте, и следующий символ сидит на младшем байте 16-битного слова.

Чтобы ответить на ваш вопрос sum & 0xFFFF, просто вычислить число, в котором более высокие 16 бит равны нулю, а младшие 16 бит совпадают с суммой. 0xFFFF - это бит-маска.

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

+0

Спасибо, что ваш комментарий был действительно полезен! i wana знаю одну последнюю вещь ... uint в сумме ... это означает, что моя сумма представляет собой целое число без знака 32 "бит: когда он говорит uint32? shoudlnt it be 16 then? – user899714

+0

Как можно дополнить это дополнение и что делает бит-маска? – user899714

+0

@ user899714 Я не думаю, что есть что-то, что связано с вычислением своего дополнения в коде, который вы p Osted. Вы можете использовать Google для расчета своего дополнения, например [здесь] (http://courses.cs.vt.edu/~csonline/NumberSystems/Lessons/OnesComplement/index.html). uint_32t - тип суммы (беззнаковое 32-битное целое число), то есть самый старший бит (MSB) из 32 бит должен ** не интерпретироваться ** как знаковый бит. Под «маскировкой» вы можете получить интересующие вас биты и игнорировать другие биты, поскольку они все обнулены маской. –

Смежные вопросы