基于 J.G. 的校验和算法弗莱彻
Posted
技术标签:
【中文标题】基于 J.G. 的校验和算法弗莱彻【英文标题】:Checksum algorithm based on J.G. Fletcher 【发布时间】:2011-11-29 17:40:46 【问题描述】:我的任务是实现基于 J.G. 的校验和算法。 Fletcher 校验和和 ISO 8473-1:1998 的描述如下:
然后他们列出了 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));
【问题讨论】:
你说有问题...也许你也应该告诉我们你为什么这么认为,如果你需要帮助... 您遇到错误了吗?它是什么?还是输出错误?怎么样? 抱歉,我想我的问题不是很清楚。在问题描述中,有四个数据与它们应该生成的校验和值一起提供给我(0x0000 = 0xFFFF;0x000000 = 0xFFFF;0xABCDEF01 = 0x9CF8;0x1456'F89A'0001 = 0x24DC)当我用我的函数尝试它时,只有前两个数据产生预期的校验和,其他数据没有给我预期值 我再次运行我的测试,这是我得到的值而不是预期的值:0xFFFF(ok),0xFFFF(ok),0xFFF2(nok?!),0xFFD5(nok?!)跨度> 我想知道这是否是字节序问题,因为我们正在使用大字节序处理器,但事实并非如此:( 【参考方案1】:您的中间总和应该是 uint16_t(或者用您的行话来说是 uint16)。
uint16_t C0, C1; // Not uint8_t.
取决于您系统上的 char
和 int
是什么(例如,不要假设 int 的位数多于 char),您的中间和可能会溢出。您的实现依赖于被提升的 uint8_t。
举例说明:
0xFF 0xFF
+0xFF +0xFF
===== =====
0x1FE % 255 = 0 0xFE % 255 = 254
^Retain ^Drop
【讨论】:
【参考方案2】:偶然发现了这个。如果有人仍然感兴趣:你在错误的方向迭代。
不要从 0 迭代到 length-1,而是从 length-1 迭代到 0,那么它会起作用。
for (i = length-1; i >= 0; i--) // and change i to 'signed'
【讨论】:
Fletcher 校验和位置相关。您必须从第一个(索引 0)迭代到最后一个(索引 N-1)元素。以上是关于基于 J.G. 的校验和算法弗莱彻的主要内容,如果未能解决你的问题,请参考以下文章