c - Fletcher 校验和从 32 位重制为 8 位

标签 c microcontroller pic crc microchip

此转换是否正确?

uint8_t fletcher8( uint8_t *data, uint8_t len )
{
    uint8_t sum1 = 0xff, sum2 = 0xff;

    while (len) {
            unsigned tlen = len > 360 ? 360 : len;
            len -= tlen;
            do {
                    sum1 += *data++;
                    sum2 += sum1;
                    tlen -= sizeof( uint8_t );
            } while (tlen);
            sum1 = (sum1 & 0xff) + (sum1 >> 4);
            sum2 = (sum2 & 0xff) + (sum2 >> 4);
    }
    /* Second reduction step to reduce sums to 4 bits */
    sum1 = (sum1 & 0xff) + (sum1 >> 4);
    sum2 = (sum2 & 0xff) + (sum2 >> 4);
    return sum2 << 4 | sum1;
    }

原文:

uint32_t fletcher32( uint16_t *data, size_t len )
{
    uint32_t sum1 = 0xffff, sum2 = 0xffff;

    while (len) {
            unsigned tlen = len > 360 ? 360 : len;
            len -= tlen;
            do {
                    sum1 += *data++;
                    sum2 += sum1;
                    tlen -= sizeof( uint16_t );
            } while (tlen);
            sum1 = (sum1 & 0xffff) + (sum1 >> 16);
            sum2 = (sum2 & 0xffff) + (sum2 >> 16);
    }
    /* Second reduction step to reduce sums to 16 bits */
    sum1 = (sum1 & 0xffff) + (sum1 >> 16);
    sum2 = (sum2 & 0xffff) + (sum2 >> 16);
    return sum2 << 16 | sum1;
    }

len 将为 8。

数据的输入为 data[] (1 - 8)

实际上我不知道如何处理这一行:unsigned tlen = len > 360? 360:长度;

也许 -> int8_t tlen = len > 255 ? 255:长度;

最佳答案

如何计算 tlen

Actually I don't know what to do with the line: unsigned tlen = len > 360 ? 360 : len;

该行似乎来自 an old versionthis Wikipedia section 。现在已经改为359,理由在talk page上有解释。 。该数字仅适用于对 16 位实体求和,因为它是满足 n 的最大数字

n(n+5)/2 × (216−1) < 232

换句话说,这是您可以在不执行模数归约的情况下添加 block 的大量次数,并且仍然避免溢出 uint32_t 。对于 4 位数据字和 8 位累加器,相应的值为 4,计算公式为

n(n+5)/2 × (24−1) < 28

因此,如果您更改数据大小,则必须修改该行。您还可以更改代码以使用更大的数据类型来保存其总和,从而在减少之前对更多 block 求和。但在这种情况下,您可能需要在循环内执行多个缩减步骤。

例如,如果您要使用 uint32_t对于 sum1sum2 ,那么您可以在溢出危险之前对 23927 个半字节求和,但之后您将需要最多 7 个 sum1 = (sum1 & 0xf) + (sum1 >> 4) 形式的缩减。将其归结为范围 1通过0x1e ,就像你原来的算法那样。将其写为 (sum1 - 1)%0xf + 1 可能会更有效。在这种情况下,您甚至可以将范围从 1 到 15 更改回 0 到 14,将总和初始化为 0 并将减少量写为 sum1 %= 0xf 。除非您需要与使用其他范围的实现兼容。

关于c - Fletcher 校验和从 32 位重制为 8 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8925018/

相关文章:

c - 如何通过sw改变LED闪烁模式

c - 在 Microchip C18 中,为什么插入 NOP 会导致更大的代码?

c - 使用 PIC 微处理器上的 C 语言进行二进制输出以实现 MIDI 输出

C fgets 与 fgetc 读取行

operating-system - 8051 称为 RTOS 的基本要求

c - RDM6300 RFID 模块与 PIC 微 Controller 的连接

timer - Timer1 RD16 位在 PIC18 微 Controller 上有什么作用?

C 代码审查 : Where is my mistake trying to solve this simple riddle?

c - 如何设置STM32生成标准的CRC32

c - 错误: ‘pthread_mutex_t’ has no member named ‘wait’