Convertir un entier en tableau d'octets (Java)


137

quel est un moyen rapide de convertir un Integeren un Byte Array?

par exemple 0xAABBCCDD => {AA, BB, CC, DD}


1
Le format du tableau d'octets résultant est-il important? Que ferez-vous avec?
skaffman

Réponses:


237

Jetez un œil à la classe ByteBuffer .

ByteBuffer b = ByteBuffer.allocate(4);
//b.order(ByteOrder.BIG_ENDIAN); // optional, the initial order of a byte buffer is always BIG_ENDIAN.
b.putInt(0xAABBCCDD);

byte[] result = b.array();

Réglage de l' ordre des assure d'octets result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCet result[3] == 0xDD.

Ou bien, vous pouvez le faire manuellement:

byte[] toBytes(int i)
{
  byte[] result = new byte[4];

  result[0] = (byte) (i >> 24);
  result[1] = (byte) (i >> 16);
  result[2] = (byte) (i >> 8);
  result[3] = (byte) (i /*>> 0*/);

  return result;
}

La ByteBufferclasse a été conçue pour ces tâches de mains sales. En fait, le private java.nio.Bitsdéfinit ces méthodes d'assistance qui sont utilisées par ByteBuffer.putInt():

private static byte int3(int x) { return (byte)(x >> 24); }
private static byte int2(int x) { return (byte)(x >> 16); }
private static byte int1(int x) { return (byte)(x >>  8); }
private static byte int0(int x) { return (byte)(x >>  0); }

3
cela fonctionnerait bien si le bytebuffer est déjà là ... sinon il semble que cela prendrait plus de temps pour faire l'allocation, que d'allouer simplement un tableau d'octets de longueur 4 et de faire le décalage manuellement ... mais nous parlons probablement sur les petites différences.
Jason S

L'instance ByteBuffer peut être mise en cache; et en interne, il est sûrement mis en œuvre avec décalage et masquage de toute façon.
Gregory Pakosz

4
C'est une très bonne réponse. Notez que big-endian est la valeur par défaut spécifiée, et les méthodes sont "chaînables", et l'argument de position est facultatif, donc tout se réduit à: byte [] result = ByteBuffer.allocate (4) .putInt (0xAABBCCDD) .array ( ); Bien sûr, si vous faites cela à plusieurs reprises et concaténez tous les résultats ensemble (ce qui est courant lorsque vous faites ce genre de chose), allouez un seul tampon et mettez à plusieurs reprisesFoo () toutes les choses dont vous avez besoin - il gardera une trace du décalage au fur et à mesure. C'est vraiment une classe extrêmement utile.
Kevin Bourrillion

qu'est-ce que cela apporte aux types signés?
Gregory Pakosz

3
Pour qui ne sait pas. PutInt écrira toujours 4 octets, quelle que soit la taille de l'entier d'entrée. Si vous ne voulez que 2 octets, utilisez putShort, etc ...
bvdb

36

Utilisation BigInteger:

private byte[] bigIntToByteArray( final int i ) {
    BigInteger bigInt = BigInteger.valueOf(i);      
    return bigInt.toByteArray();
}

Utilisation DataOutputStream:

private byte[] intToByteArray ( final int i ) throws IOException {      
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    dos.writeInt(i);
    dos.flush();
    return bos.toByteArray();
}

Utilisation ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}

5
faites attention à l'ordre des octets
Gregory Pakosz

1
ByteBuffer donne-t-il un int non signé?
Arun George

@Pascal Utilisation de ByteBuffer J'ai essayé avec ByteBuffer bb = ByteBuffer.allocate (3); Pour cela, il donne java.nio.BufferOverflowException, je ne comprends pas pourquoi il ne fonctionne pas pour une valeur inférieure à 4? Pouvez-vous expliquer?
Sanjay Jain

@SanjayJain Vous obtenez une exception de dépassement de mémoire tampon car les entiers en Java ont une taille de 32 bits ou 4 octets et vous obligent donc à allouer au moins 4 octets de mémoire dans votre ByteBuffer.
choquant le

@GregoryPakosz a raison sur l'ordre des octets. Sa réponse en utilisant ByteBufferest plus intuitive si vous avez affaire à un int supérieur à 2 ^ 31 - 1.
ordonezalex

31

utilise cette fonction ça marche pour moi

public byte[] toByteArray(int value) {
    return new byte[] {
            (byte)(value >> 24),
            (byte)(value >> 16),
            (byte)(value >> 8),
            (byte)value};
}

il traduit l'int en une valeur d'octet


Cela ne vaut rien non plus que cela fonctionne quel que soit le bit le plus significatif et plus efficace par rapport aux autres réponses. Peut également utiliser «>>».
algolicious le

1
Une solution directe comme celle-ci est certainement plus rapide que d'appeler une méthode de bibliothèque. Parfois, vous devez simplement manipuler les bits directement avec quelques lignes de code plutôt que d'encourir toute la surcharge supplémentaire des appels de méthode de bibliothèque.
David R Tribble

Et cela convertit bien les langues, ce qui est bon pour le développement de logiciels multilingues.
The Coordinator

15

Si vous aimez Guava , vous pouvez utiliser sa Intsclasse:


Pour intbyte[], utilisez toByteArray():

byte[] byteArray = Ints.toByteArray(0xAABBCCDD);

Le résultat est {0xAA, 0xBB, 0xCC, 0xDD}.


Son inverse est fromByteArray()ou fromBytes():

int intValue = Ints.fromByteArray(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD});
int intValue = Ints.fromBytes((byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD);

Le résultat est 0xAABBCCDD.


8

Vous pouvez utiliser BigInteger:

À partir des nombres entiers:

byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

Le tableau retourné a la taille nécessaire pour représenter le nombre, il peut donc être de taille 1, pour représenter 1 par exemple. Toutefois, la taille ne peut pas être supérieure à quatre octets si un int est passé.

À partir de chaînes:

BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

Cependant, vous devrez faire attention, si le premier octet est plus élevé 0x7F(comme c'est le cas dans ce cas), où BigInteger insère un octet 0x00 au début du tableau. Ceci est nécessaire pour faire la distinction entre les valeurs positives et négatives.


Merci! Mais comme il s'agit de BigInteger, les ints s'enrouleront-ils correctement? Ce sont des entiers qui sont en dehors de Integer.MAX_VALUE mais peuvent toujours être représentés avec seulement 4 octets?
Buttercup

1
Ce n'est certainement pas rapide à exécuter. ;)
Peter Lawrey

Ce n'est pas une bonne option. Non seulement il peut ajouter l'octet 0x00, mais également supprimer les zéros non significatifs.
ZZ Coder

1

Solution simple qui gère correctement ByteOrder:

ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(yourInt).array();


1

très facile avec Android

int i=10000;
byte b1=(byte)Color.alpha(i);
byte b2=(byte)Color.red(i);
byte b3=(byte)Color.green(i);
byte b4=(byte)Color.blue(i);

1

Cela vous aidera.

import java.nio.ByteBuffer;
import java.util.Arrays;

public class MyClass
{
    public static void main(String args[]) {
        byte [] hbhbytes = ByteBuffer.allocate(4).putInt(16666666).array();

        System.out.println(Arrays.toString(hbhbytes));
    }
}

0

Peut aussi changer -

byte[] ba = new byte[4];
int val = Integer.MAX_VALUE;

for(byte i=0;i<4;i++)
    ba[i] = (byte)(val >> i*8);
    //ba[3-i] = (byte)(val >> i*8); //Big-endian

0

Voici une méthode qui devrait faire le travail correctement.

public byte[] toByteArray(int value)
{
    final byte[] destination = new byte[Integer.BYTES];
    for(int index = Integer.BYTES - 1; index >= 0; index--)
    {
        destination[i] = (byte) value;
        value = value >> 8;
    };
    return destination;
};

0

C'est ma solution:

public void getBytes(int val) {
    byte[] bytes = new byte[Integer.BYTES];
    for (int i = 0;i < bytes.length; i ++) {
        int j = val % Byte.MAX_VALUE;
        bytes[i] = (j == 0 ? Byte.MAX_VALUE : j);
    }
}

Aussi Stringy méthode:

public void getBytes(int val) {
    String hex = Integer.toHexString(val);
    byte[] val = new byte[hex.length()/2]; // because byte is 2 hex chars
    for (int i = 0; i < hex.length(); i+=2)
        val[i] = Byte.parseByte("0x" + hex.substring(i, i+2), 16);
    return val;
}
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.