Algorithme de sum de contrôle basé sur JG Fletcher

J’ai été chargé de mettre en œuvre un algorithme de sum de contrôle basé sur la sum de contrôle de JG Fletcher et sur la norme ISO 8473-1: 1998.

entrez la description de l'image ici

Ils énumèrent ensuite 4 données qui peuvent être vérifiées pour voir si l’algo est correct mais ma version échoue aux deux dernières valeurs.
0000 donne une sum de contrôle de FFFF
0000’00 donne une sum de contrôle de FFFF
ABCDEF’01 donne une sum de contrôle de 9CF8
1456’F89A’0001 donne une sum de contrôle de 24DC

J’y travaille depuis des heures et je ne trouve pas ce que j’ai fait de mal. Une nouvelle paire d’yeux pourrait nous aider énormément.

Voici ma fonction:

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

Vos sums intermédiaires doivent être uint16_t (ou uint16 dans votre jargon).

 uint16_t C0, C1; // Not uint8_t. 

En fonction de ce que sont char et int sur votre système (par exemple, ne supposez pas que int a plus de bits que char), vos sums intermédiaires peuvent déborder . Votre implémentation dépend de la promotion de uint8_t.

Pour illustrer:

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

Je suis juste tombé sur ça. Si quelqu’un est toujours intéressé, vous parcourez la mauvaise direction.

NE PAS itérer de 0 à longueur-1 mais de longueur-1 à 0, alors cela fonctionnera.

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