基于J.G.的校验和算法弗莱彻

时间:2011-11-29 17:40:47

标签: c checksum

我的任务是实现基于J.G.的Checksum算法。 Fletcher校验和和ISO 8473-1:1998并且描述如下:

enter image description here

然后他们列出了4个可以检查的数据,以查看算法是否正确,但我的版本在最后两个值处失败。
0000给出了FFFF的校验和 0000'00给出了FFFF的校验和 ABCDEF'01给出了9CF8的校验和 1456'F89A'0001给出24DC的校验和

我一直在研究这个问题好几个小时,找不到我做错了什么,一套新的眼睛可以帮助我。

这是我的功能:

uint16 Crc_CalculateISOChecksum(uint8 *pt_start_address, uint32  length)
{
    uint8 C0, C1;
    uint8 data;
    uint32 i;
    uint8 ck1, ck2;

    /* Initial value */
    C0 = 0;
    C1 = 0;

    /* memories - 32bits wide*/
    for (i=0; i<length; i++)    /* nb_bytes has been verified */
    {
      data = pt_start_address[i];   
      C0 = (C0 + data)%255;
      C1 = (C1 + C0)%255;
    }
    /* Calculate the intermediate ISO checksum value */
    ck1 = (unsigned char)(255-((C0+C1)%255));
    ck2 =  (unsigned char)(C1%255);
    if (ck1 == 0)
    {
      ck1 = MASK_BYTE_LSB;
    }
    if (ck2 == 0)
    {
        ck2 = MASK_BYTE_LSB;
    }
    return ((((uint16)ck1)<<8) | ((uint16)ck2));    
}

2 个答案:

答案 0 :(得分:2)

您的中间数应为 uint16_t (或您的术语中的uint16)。

uint16_t C0, C1; // Not uint8_t.

取决于系统上的charint(例如,假设int的位数多于char),您的中间总和可能溢出。您的实现依赖于uint8_t被提升。

举例说明:

 0xFF               0xFF
+0xFF              +0xFF
=====              =====
0x1FE % 255 = 0     0xFE % 255 = 254
  ^Retain            ^Drop

答案 1 :(得分:-1)

偶然发现了这一点。如果有人仍然感兴趣:你向错误的方向迭代。

不要从0迭代到长度-1,而是从长度-1迭代到0,然后它会起作用。

for (i = length-1; i >= 0; i--) // and change i to 'signed'