Comment convertir un tableau d'octets en sa valeur numérique (Java)?


89

J'ai un tableau de 8 octets et je veux le convertir en sa valeur numérique correspondante.

par exemple

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

Je veux une méthode qui effectuera l'opération de conversion ci-dessus.


4
Qu'entendez-vous par «valeur numérique»? Les octets représentent-ils un nombre entier (long) ou flottant (double) en binaire? Sont-ils la représentation sous forme de chaîne d'un nombre? Ou encore une autre représentation?
starblue


NB: le lien de TacB0sS était ce que je recherchais en fait - à la fois la conversion en avant et en arrière.
Jay Taylor

new BigInteger(by).longValue()
Marquis of Lorne

Réponses:


106

En supposant que le premier octet est l'octet le moins significatif:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Le premier octet est-il le plus significatif, alors c'est un peu différent:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Remplacez long par BigInteger , si vous avez plus de 8 octets.

Merci à Aaron Digulla pour la correction de mes erreurs.


8
-1 octets sont des valeurs signées! Et remplacez pow () par shift (<<)! "value = (value << 8) + (by [i] & 0xff)"
Aaron Digulla

L'opérateur de décalage (<<) a-t-il une priorité de droite à gauche? Comment fonctionne le code ci-dessus? Cela fonctionne très bien pour moi. Je veux juste savoir le fonctionnement. Merci d'avance
suraj

@Mnementh: L'opérateur de décalage (<<) a-t-il une priorité de droite à gauche? Comment fonctionne le code ci-dessus? Cela fonctionne très bien pour moi. Je veux juste savoir le fonctionnement. Merci d'avance
suraj

5
Au cas où quelqu'un d'autre aurait le même problème que moi, dans le premier exemple, par [i] doit être converti en long, sinon cela ne fonctionne que pour les valeurs inférieures à 2 ^ 32. Autrement dit,value += ((long)by[i] & 0xffL) << (8 * i);
Luc

115

On pourrait utiliser les Buffers qui sont fournis dans le cadre du java.niopackage pour effectuer la conversion.

Ici, le byte[]tableau source a une de longueur 8, qui est la taille qui correspond à une longvaleur.

Tout d'abord, le byte[]tableau est encapsulé dans a ByteBuffer, puis la ByteBuffer.getLongméthode est appelée pour obtenir la longvaleur:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

Résultat

4

Je tiens à remercier dfa pour avoir indiqué la ByteBuffer.getLongméthode dans les commentaires.


Bien que cela ne soit peut-être pas applicable dans cette situation, la beauté du Buffers vient de regarder un tableau avec plusieurs valeurs.

Par exemple, si nous avions un tableau de 8 octets et que nous voulions le voir sous forme de deux intvaleurs, nous pourrions envelopper le byte[]tableau dans un ByteBuffer, qui est considéré comme un IntBufferet obtenir les valeurs par IntBuffer.get:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

Résultat:

1
4

qu'en est-il de ByteBuffer.wrap (nouvel octet [] {0, 0, 0, 1, 0, 0, 0, 4}). getLong ()? cette méthode devrait lire les 8 octets suivants et les convertir en un long
dfa

@dfa: Merci d'avoir signalé cela, cela semble fonctionner - je vais éditer la réponse. :)
coobird

16

S'il s'agit d'une valeur numérique de 8 octets, vous pouvez essayer:

BigInteger n = new BigInteger(byteArray);

S'il s'agit d'un tampon de caractères UTF-8, vous pouvez essayer:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));

J'aurais voté pour cette réponse si elle se terminait juste après le premier extrait de code, ou si elle incluait du code pour convertir la chaîne en "valeur numérique". En l'état, la seconde moitié de votre réponse semble être un non-séquentiel.
Laurence Gonsalves

Pas ce que je voulais dire en premier lieu, j'ai changé ma réponse
Vincent Robert


9

Vous pouvez également utiliser BigInteger pour les octets de longueur variable. Vous pouvez le convertir en Long, Integer ou Short, selon vos besoins.

new BigInteger(bytes).intValue();

ou pour désigner la polarité:

new BigInteger(1, bytes).intValue();


1

Chaque cellule du tableau est traitée comme un entier non signé:

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}

Juste une note que je devais utiliser 0xFFL, sinon le cast de int 0xFF à long avait beaucoup de bits incorrects définis lorsque j'ai imprimé Long.toHexString (l).
Luke

Vous devez utiliser 0xFFL sinon vous obtenez l'extension de signe.
Gris
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.