2011-11-29 322 views
2

我的任务是实现基于J.G.的Checksum算法。弗莱彻校验和ISO 8473-1:1998年,描述像这样:基于J.G.的校验和算法Fletcher

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));  
} 
+3

你说什么是错的...也许你也应该告诉我们,为什么你认为,如果你想帮助... – Macmade

+1

你得到一个错误?它是什么?或者是输出错误?怎么样? – Kevin

+0

对不起,我猜这是不是很清楚我的问题是什么。在问题描述中,有四个数据是根据他们应该生成的校验和值给我的(0x0000 = 0xFFFF; 0x000000 = 0xFFFF; 0xABCDEF01 = 0x9CF8; 0x1456'F89A'0001 = 0x24DC)当我用我的函数尝试它时,前两个数据产生期望的校验和,其他数据不给我期望值 – Leo

回答

1

你的中间和值应该是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

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

不要从0迭代到长度1,而是从长度-1到0,然后它将工作。

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

为什么downvote? –

+0

[** Fletcher **](http://en.wikipedia .org/wiki/Fletcher%27s_checksum)校验和是** pos银行足球比赛相关的**。您必须从第一个(索引0)到最后一个(索引N-1)元素进行迭代。 –