I need to compare given text data with checkSumCalculator method and I try to send the data with command method. I find and changed the code according to my own needs. But I dont understand some parts. How can 0x00 hex char will be increase with given data? and how/what is the point of comparing check_data with 0xFF? How to extract (check_data & 0xFF) from 0x100 hex? I am very confused.
void Widget::command()
{
std::string txt = "<DONE:8022ff";
unsigned char check_sum = checkSumCalculator(&txt[0], txt.size());
QString reply= QString::fromStdString(txt) + QString("%1>").arg(check_sum, 2, 16,
QChar('0'));
emit finished(replyMessage, true);
}
static unsigned char checkSumCalculator(void *data, int length)
{
unsigned char check_data = 0x00;
for (int i = 0; i < lenght; i++)
check_data+= ((unsigned char*)data)[i];
check_data = (0x100 - (check_data & 0xFF)) & 0xFF;
return check_data;
}
checkSumCalculator
starts by adding together all the values of the buffer in data
. Because the type of data
is unsigned char
, this sum is done modulo 0x100 (256), 1 more than the maximum value an unsigned char
can handle (0xFF = 255); the value is said to "wrap around" ((unsigned char) (0xFF + 1)
= 256) is again 0
).
These two lines:
check_data = (0x100 - (check_data & 0xFF)) & 0xFF;
return check_data;
are really more complicated than it's needed. All that would be needed would be:
return -check_data;
That is, at the end it negates the value. Because the arithmetic is modulo 256, this is essentially the same as flipping the bits and adding 1 (-check_data = ~check_data + 1). This is instead implemented in a more convoluted way:
check_data & 0xFF
doesn't do much, because it's a bitwise AND with all the possible bits that can be set on an unsigned char
. The value is promoted to an unsigned int (due to C's default integer promotions) where all the bits higher than the lower 8 are necessarily 0. So this is the same as (unsigned int)check_data
. Ultimately, this promotion has no bearing on the result.-check_data
, as far as the lower 8 bits are concerned (which what we end up caring about).& 0xFF
is also redundant because even though the expression was promoted to unsigned int, it will converted as an unsigned char by returning.