Calcul de Checksum - en complément à deux de la somme de tous les octets
J'ai des instructions sur la création d'une somme de contrôle d'un message décrit comme ceci:
La somme de contrôle est constitué d'un seul octet égal au complément à deux de la somme de tous les octets à partir de la “type de message” mot jusqu'à la fin du bloc de message (à l'exclusion de la transmission de la somme de contrôle). À partir de l'octet le plus significatif est ignoré.
Une autre description, j'ai trouvé:
La valeur de somme de contrôle contient le complément à deux de la modulo 256 somme des autres mots dans le message de données (c'est à dire, le type de message, la longueur du message, et les mots de données). Le matériel de réception peut calculer le modulo 256 somme des mots et d'ajouter cette somme au reçu de la somme de contrôle parole. Un résultat de zéro indique généralement que le message a été correctement reçu.
Je comprends ce à dire que la somme de la valeur de tous les octets du message (à l'excl somme de contrôle), d'obtenir modulo 256 de ce nombre. obtenez complément à deux de ce numéro et c'est mon checksum.
Mais j'ai de la difficulté avec un exemple exemple de message (de la conception doc donc je dois supposer qu'il a été encodé correctement).
unsigned char arr[] = {0x80,0x15,0x1,0x8,0x30,0x33,0x31,0x35,0x31,0x30,0x33,0x30,0x2,0x8,0x30,0x33,0x35,0x31,0x2d,0x33,0x32,0x31,0x30,0xe};
De sorte que le dernier octet, 0xE, est la somme de contrôle. Mon code pour calculer la somme de contrôle est comme suit:
bool isMsgValid(unsigned char arr[], int len) {
int sum = 0;
for(int i = 0; i < (len-1); ++i) {
sum += arr[i];
}
//modulo 256 sum
sum %= 256;
char ch = sum;
//twos complement
unsigned char twoscompl = ~ch + 1;
return arr[len-1] == twoscompl;
}
int main(int argc, char* argv[])
{
unsigned char arr[] = {0x80,0x15,0x1,0x8,0x30,0x33,0x31,0x35,0x31,0x30,0x33,0x30,0x2,0x8,0x30,0x33,0x35,0x31,0x2d,0x33,0x32,0x31,0x30,0xe};
int arrsize = sizeof(arr) / sizeof(arr[0]);
bool ret = isMsgValid(arr, arrsize);
return 0;
}
La spec est ici:= http://www.sinet.bt.com/227v3p5.pdf
Je suppose que j'ai mal compris l'algorithme nécessaire. Une idée de comment créer cette somme de contrôle?
Flippin spec écrivain fait une erreur dans les données exemple. Juste repéré ce puis revint sur ici et trouvé d'autres repéré aussi. Désolé si j'ai perdu votre temps. Je vais étudier les réponses, car il semble que certains des commentaires utiles pour améliorer mon code.
La somme de contrôle est correcte. Voir ma réponse.
Sachez que si une des valeurs est un de moins et une autre valeur est un plus, la somme de contrôle va passer. Par exemple, l'ensemble {1,2,3,4,5}, invalide ensemble (mais réussi) {1,3,3,3,5}. Cette sorte de somme de contrôle erreur m'a coûté 4 jours de débogage!
OriginalL'auteur Angus Comber | 2012-09-02
Vous devez vous connecter pour publier un commentaire.
Vous miscopied l'exemple de message à partir d'un pdf liées. Le deuxième paramètre de la longueur est de 9 octets, mais vous avez utilisé 0x08 dans votre code.
Le document stipule à tort "8 octets dans la troisième colonne quand il y a vraiment de 9 octets du paramètre. La deuxième colonne indique bien "00001001".
En d'autres termes, votre message de test devrait être:
Avec le bon message tableau,
ret == true
quand j'ai essayer votre programme.Pas de problème. Vous devez prendre l'avis des autres sur l'utilisation de types non signés.
OriginalL'auteur Emile Cormier
D'accord avec le commentaire: il semble bien que la somme de contrôle est mauvais. Où dans le .PDF est-ce des données?
Quelques conseils généraux:
Utiliser un type non signé comme l'accumulateur, qui vous donne bien défini comportement sur le dépassement, et vous en aurez besoin pour des messages plus longs. De même, si vous stockez le résultat dans une variable char, faire unsigned char.
Mais vous n'avez pas besoin de le stocker; il suffit de faire le calcul avec un type non signé, de les compléter, le résultat, ajouter 1, et masque les bits de sorte que vous obtenez une 8-bit de résultat.
Aussi, il y a un truc ici, si vous êtes sur le matériel qui utilise deux-complément de l'arithmétique: il suffit d'ajouter toutes les valeurs, y compris la somme de contrôle, puis masquer les bits élevés; le résultat sera 0 si l'entrée est correcte.
OriginalL'auteur Pete Becker
Il est beaucoup plus facile d'utiliser cette condition pour comprendre la somme de contrôle:
Comme les autres l'ont dit, vous devriez vraiment utiliser unsigned types lorsque vous travaillez avec des bits individuels. Cela est également vrai quand on fait de l'arithmétique modulaire. Si vous utilisez des types signés, vous laissez-vous ouvrir plutôt à un grand nombre de signer des erreurs liées à la. Otoh, que, à peu près la seule erreur que vous vous ouvrez à l'aide de nombres non signés est des choses comme oublier
2u-3u
est un nombre positif.(faire attention sur le mélange signés et non signés, les chiffres: il y a beaucoup de subtilités impliqués dans ce trop)
OriginalL'auteur Hurkyl