Question

Je calculais 16 bits somme de contrôle sur mes données que je dois envoyer au serveur où il doit recalculer et correspondre avec la somme de contrôle fourni. valeur checksum que je reçois est en entier, mais j'ai seulement 2 octets pour l'envoi du value.So je suis coulée int à short tout en appelant la méthode de shortToBytes. Cela fonctionne bien jusqu'à ce que la valeur de contrôle est inférieure à 32767 après, je reçois des valeurs négatives.

La chose est java ne pas primitives non signés, donc je ne suis pas en mesure d'envoyer des valeurs supérieures à la valeur maximale de short signée autorisée.

Comment puis-je faire cela, la conversion int à court et à envoyer sur le réseau sans se soucier de troncature et signé et unsigned int.

En outre, tant du côté que j'ai exécution du programme java.

   private byte[] shortToBytes(short sh) {
        byte[] baValue = new byte[2];
        ByteBuffer buf = ByteBuffer.wrap(baValue);
        return buf.putShort(sh).array();
    }

    private short bytesToShort(byte[] buf, int offset) {
        byte[] baValue = new byte[2];
        System.arraycopy(buf, offset, baValue, 0, 2);
        return ByteBuffer.wrap(baValue).getShort();
    }
Était-ce utile?

La solution

Vous obtenez toujours la même valeur binaire que le serveur. Donc, pour voir la droite valeur numérique remplacer le ByteBuffer.wrap(baValue).getShort() à un ByteBuffer.wrap(baValue).getInt(). Cela devrait vous donner la même valeur numérique que le serveur.

Autres conseils

char est un type de 16 bits non signé. En fait, il est le seul type non signé en Java. Vous pouvez l'utiliser pour calculer la somme de contrôle, puis utiliser un ByteBuffer pour obtenir les octets ou utiliser simplement et à droite et au niveau du bit de décalage pour obtenir les octets.

Gardez à l'esprit que bytes sont signés.

Tout d'abord, Java types int, short et byte sont tous signés pas non signé. En second lieu, lorsque vous lancez un Java int à un short, etc, vous obtiendrez troncature silence.

Que cela est important dépend de la nature de l'algorithme de contrôle. S'il est une simple somme, ou un algorithme il y a une bitwise bonne chance que l'algorithme est très bien mis en œuvre en utilisant Java des entiers signés. Par exemple, ces 16bit « négatives » checksum pourrait être correcte quand elle est interprétée par quelque chose attend des valeurs non signées.

D'autre part, la sémantique de la multiplication et la division sont telles que les arômes signés et non signés doivent être traitées séparément. (Au moins, c'est ce que je déduis de l'approche non scientifique de regarder le jeu d'instructions x86 ... qui a des instructions distinctes pour signée par rapport à la multiplication et la division non signée).

EDIT Je comprends que vous calculez CRC-16. Depuis peut être calculée en déplaçant et XOR, il devrait y avoir aucune inquiétude au sujet signé par rapport à des nombres non signés lors du calcul.

En bref, vous n'avez rien à craindre.

Quand vous dites que vous obtenez des valeurs négatives, je suppose que vous voulez dire quand vous lisez la valeur 16 bits et de le convertir en un entier. La raison est que l'extension de signe provoque le bit le plus significatif (qui est un 1) à répliquer lorsque le short est élargi à un int. La solution simple consiste à niveau du bit et le nombre entier reconstitué avec 0xFFFF, qui fera en sorte que seuls les 16 bits les moins signficant sont non nuls.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top