我的任务是实现基于J.G.的Checksum算法。 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));
}
答案 0 :(得分:2)
您的中间数应为 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
答案 1 :(得分:-1)
偶然发现了这一点。如果有人仍然感兴趣:你向错误的方向迭代。
不要从0迭代到长度-1,而是从长度-1迭代到0,然后它会起作用。
for (i = length-1; i >= 0; i--) // and change i to 'signed'