8
votes

Calcul de la somme de contrôle dans Android / Java

J'ai écrit une fonction de calcul de checksum dans Android / Java. La fonction comme suit

void CalculateCheckSum( byte[] bytes ){
     short CheckSum = 0, i = 0;
     for( i = 0; i < bytes.length; i++ ){
        CheckSum = (short) ((short)CheckSum + (short)bytes[i]);
     }

     Log.i("Checksum", Integer.toHexString(CheckSum));
}


0 commentaires

6 Réponses :


1
votes

octet selon Java Docs :

La valeur d'un octet est allée entre 2 ^ (- 7) et (2 ^ 7) -1 (-128 à 127).

Mais votre valeur 0xef (en décimal 239) a déjà atteint la limite d'un octet. C'est ce que la somme donne les mauvais nombres.


4 commentaires

Est un type de données qui prend en charge la valeur de 8 bits (c'est-à-dire 0-255) en Java


Il n'y a pas de type non signé de type primitif dans Java Afaik. Mais vous pouvez trouver d'autres dépendances qui fournit non signé type .


Essayez ceci Link


0xef s'inscrit dans un octet. Il suffit de la valeur -17 lorsque vous l'utilisez dans une expression. Que seul ne perturbera pas le calcul.



2
votes

Utilisez un débogueur et déboguer votre code. Généralement, si vous continuez à ajouter des trucs, même si vous utilisez un int ou un long , il est lié à débordement à un moment donné, vous obtiendrez ainsi des résultats inattendus. Il est préférable d'utiliser un algorithme de contrôle standard ou l'une des classes déjà disponibles telles que CRC32 ou adler31 . Quant à votre code, vous semblez traiter le résultat comme un entier, alors pourquoi lancer à court en premier lieu?

Java fait tous les calculs arithmétiques utilisant int 'S, donc votre octet s est converti en int et ceux qui ne correspondent pas à un octet ressembleront à ceci comme int ' S: ffffffef (-17). Naturellement, vous n'avez besoin que de la valeur d'octet réelle, vous devez donc vous éteindre tout le reste en utilisant (0xFF & B) . Donc, votre boucle que de devient quelque chose comme ceci: xxx


1 commentaires

Je souhaite envoyer un peu de paquet à un équipement incorporé qui utilise la méthode de contrôle ci-dessus pour calculer. donc je ne peux pas changer CRC32 ou autre



-1
votes

Vous devez utiliser des entiers comme entrée si vous les convertissez avec:

    String CalculateCheckSum( Integer[] bytes ){
        Integer CheckSum = 0, i = 0;
        for( i = 0; i < bytes.length; i++ ){
            CheckSum += bytes[i];
        }
        return Integer.toHexString(CheckSum);
    }


1 commentaires

Mais il n'a pas d'entiers ni d'entiers, comme entrée.



1
votes

Comme mentionné ci-dessus par Aprian, tandis que l'octet dispose des 8 bits nécessaires pour vos valeurs hexagonales, il ne peut stocker que les valeurs entre -128 et 127. Donc, une solution rapide et facile serait d'utiliser la prochaine primitive plus grande, dans ce cas court code>. xxx pré>

qui me donne la sortie: p>

Checksum: ce4


1 commentaires

Cela signera toujours. Vous devez masquer.



2
votes

Le problème ici est le (court) coulée de octets [i] . Il étend le signe. Vous devriez changer (court) octets [i] sur (octets [i] & 0XFF) . Cela vous donnera la bonne réponse.

Cela n'a rien à voir avec le débordement des octets, contrairement à la plupart des autres réponses. Vous n'avez pas à changer le type de tableau non plus.


0 commentaires

0
votes

Enfin, j'ai eu ...

Code corrigé xxx

Merci à Taprian et d'autres


1 commentaires

Merci à Taprian? Il était complètement faux et il ne vous a pas donné ce code. Seules deux réponses vous ont donné ce code et vous devez en accepter l'une de celles-ci, pas la vôtre. Poster le vôtre lorsque ces autres existent est une perte de temps et d'espace.