使用给定数据增加十六进制值

Increasing hex value with given data

我需要用 checkSumCalculator 方法比较给定的文本数据,我尝试用命令方法发送数据。我根据自己的需要找到并更改了代码。但我不明白某些部分。 0x00 十六进制字符如何随给定数据增加? how/what 是将 check_data 与 0xFF 进行比较的重点?如何从 0x100 十六进制中提取 (check_data & 0xFF)?我很困惑。

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 首先将 data 中缓冲区的所有值加在一起。因为 data 的类型是 unsigned char,这个和是对 0x100 (256) 求模的,比 unsigned char 可以处理的最大值 (0xFF = 255) 多 1;该值被称为“环绕”((unsigned char) (0xFF + 1) = 256) 又是 0).

这两行:

    check_data = (0x100 - (check_data & 0xFF)) & 0xFF;
    return check_data;

确实比需要的更复杂。所需要的只是:

    return -check_data;

也就是说,最后它取反了这个值。因为算术是对 256 取模,所以这在本质上与翻转位并加 1 (-check_data = ~check_data + 1) 相同。这是以更复杂的方式实现的:

  • check_data & 0xFF 作用不大,因为它是一个按位与,可以在 unsigned char 上设置所有可能的位。该值被提升为无符号整数(由于 C 的默认整数提升),其中所有高于低 8 位的位都必须为 0。因此这与 (unsigned int)check_data 相同。归根结底,这次升职与结果无关。
  • 就低 8 位而言(这是我们最终关心的),从 0x100 减去与 -check_data 相同。
  • 最后的 & 0xFF 也是多余的,因为即使表达式被提升为 unsigned int,它也会通过返回转换为 unsigned char。