Может кто-нибудь объяснить, что делает этот код? Я должен интерпретировать этот код и использовать его в качестве кода контрольной суммы, но я не уверен, является ли он абсолютно правильным. Особенно, как работают переполнения и что *cp, const char* cp
а также sum & 0xFFFF
имею в виду? Основная идея состояла в том, чтобы получить входные данные от пользователя и преобразовать их в двоичную форму по 16 бит за раз. Затем сложите все кратные 16 битов (в двоичном виде) и получите 16-битную сумму. Если в дополнении есть бит переполнения, добавьте его в lsb
итоговой суммы Затем возьмите одно дополнение к результату.
Насколько близок этот код к описанному выше?
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;
}
Я вижу несколько проблем в коде:
cp
является указателем на нулевой массив символов, содержащий входное сообщение. while(*cp)
будет иметь проблемы как внутри цикла while cp
увеличивается на 2 !!! Так что довольно легко пропустить финал \0
массива char (например, входное сообщение имеет 2 символа) и приведет к ошибке сегментации.*(cp)
а также *(cp-1)
получить два соседних символа (байта) во входном сообщении. Но почему двухбайтовое слово образовано *(cp-1)>>8 + *(cp)
? Я думаю, что имеет смысл сформировать 16-битное слово *(cp-1)<<8 + *(cp)
то есть предыдущий символ находится в старшем байте, а следующий символ — в младшем байте слова из 16 битов.Ответить на ваш вопрос sum & 0xFFFF
просто означает вычисление числа, где старшие 16 бит равны нулю, а младшие 16 битов совпадают с суммой. 0xFFFF
немного маски
Самое смешное, что даже приведенный выше код может не выполнять то, что вы упомянули в качестве требования, если отправляющая и получающая стороны используют один и тот же фрагмент неверного кода, создание и проверка контрольной суммы пройдут, поскольку оба конца согласованы друг с другом:)
Других решений пока нет …