有人可以解释这段代码在做什么吗?我必须解释这个代码并将其用作校验和代码,但我不确定它是否绝对正确。特别是溢出如何工作以及*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;
}
答案 0 :(得分:0)
我在代码中看到了几个问题:
cp
是一个指向零结束char数组的指针,用于保存输入消息。 while(*cp)
会有问题,因为while循环体cp
内增加了2!因此,跳过char数组的结尾\0
相当容易(例如输入消息有2个字符)并导致分段错误。*(cp)
和*(cp-1)
获取输入消息中的两个相邻字符(字节)。但为什么两个字节的单词由*(cp-1)>>8 + *(cp)
组成?我认为用*(cp-1)<<8 + *(cp)
形成16位字是有意义的,即前面的字符位于高位字节,后面的字符位于16位字的低位字节。回答你的问题sum & 0xFFFF
只是意味着计算一个数字,其中高16位为零,低16位与总和相同。 0xFFFF
有点掩盖。
有趣的是,即使上面的代码可能没有按照您提到的要求做出准确的事情,只要发送方和接收方使用相同的错误代码,您的校验和创建和验证就会通过,因为结尾彼此一致:)