我正在尝试实现一个函数来为可变长度的内存区域计算8位Fletcher的校验和,其想法是我可以传递2字节的短字节或2kb的数组并使用相同的函数。我今天才研究它,所以我绝对不是校验和算法或指针算术方面的专家,而且我的代码几乎肯定充满了错误。

基本上,我的策略是将指针传递给组中第一个字节的地址以及要扫描的内存区域的大小,只要大小始终为sizeof(要传递的对象),它将被有效。我可以在函数内计算sizeof以避免潜在的错误,但是我认为必须将接受的类型限制为特定类型。

现在,据我了解,*(ptr + i)应该返回位于ptr地址之后的第i个字节中的值。我以前没有做过这样的事情,所以我可能会误解我读到的内容。

uint8_t fletcher_8(void *data, uint size){
        data = (uint8_t *)data; // Recast pointer as uint8_t*
        uint8_t sum1 = 0;
        uint8_t sum2 = 0; // Initialise variables for algorithm
        for (int i =0; i < size; i++){
            sum1 += *(data + i);     // get the value of the ith byte after the data pointer's address
            sum2 += sum1;
        }
        sum1 %= 16; // modulo the first sum
        sum1 << 4;  // shift lower four bits to the upper four bits
        sum2 %= 16; // modulo the second sum
        return sum1 + sum2; // add both sums (highest four bits are sum1, lower four bits are sum2
    }

如果我完全疯了,并且有任何更简单的方法来实现我想要做的事情,我很想听听!

编辑:

我专门询问C++实现,但是上面的代码也可能是psudocode。我最想知道我的方法是否正确才是最重要的。

最佳答案

您的第一个版本比第二个版本好。

第二版中的一些错误:

  • data的类型不应为void *,否则*(data + i)是编译时错误。 data = (uint8_t *)data;不执行任何操作。
  • sum1 << 4;错过了=做任何事情:sum1 <<= 4;
  • isize应该是同一类型。我更喜欢size_t,因为它是sizeof返回的类型。
  • https://en.wikipedia.org/wiki/Fletcher%27s_checksum说更高的位应该是sum2,您的是sum1中的位。

  • 我会这样写
    uint8_t fletcher_8(uint8_t *data, size_t size){
        uint8_t sum1 = 0;
        uint8_t sum2 = 0;
        for (size_t i = 0; i < size; i++){
            sum1 += data[i];
            sum2 += sum1;
        }
        return (sum1 & 0xF) | (sum2 << 4);
    }
    

    要么
    uint8_t fletcher_8(uint8_t *data, size_t size){
        uint8_t sum1 = 0;
        uint8_t sum2 = 0;
        while (size--){
            sum1 += *data++;
            sum2 += sum1;
        }
        return (sum1 & 0xF) | (sum2 << 4);
    }
    

    关于c++ - Fletcher的校验和,用于任意长度的字节组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34147580/

    10-11 23:02
    查看更多