Tableau d'entiers Java en octets

191

J'ai un entier: 1695609641

quand j'utilise la méthode:

String hex = Integer.toHexString(1695609641);
system.out.println(hex); 

donne:

6510f329

mais je veux un tableau d'octets:

byte[] bytearray = new byte[] { (byte) 0x65, (byte)0x10, (byte)0xf3, (byte)0x29};

Comment puis-je faire ça?

Stefan
la source
4
duplication possible de Convertir un entier en tableau d'octets (Java)
finnw
Double

Réponses:

294

l'utilisation de ByteBuffer de Java NIO est très simple:

byte[] bytes = ByteBuffer.allocate(4).putInt(1695609641).array();

for (byte b : bytes) {
   System.out.format("0x%x ", b);
}

production:

0x65 0x10 0xf3 0x29 
dfa
la source
4
Ou utilisez le format "0x%02X"si vous voulez toujours deux caractères hexadécimaux ainsi que des hexadécimaux majuscules, par exemple des System.out.format("0x%02X", (byte) 10)affichages 0x0A.
Maarten Bodewes
12
Vous pouvez utiliser Integer.SIZE / 8 pour éviter de coder en dur le 4, qui est un modèle qui fonctionne bien pour d'autres types comme Long.
davenpcj
3
@davenpcj Vous pouvez même utiliser Integer.SIZE / Byte.SIZE
rkosegi
11
@rkosegi Ou même Integer.BYTES depuis Java 8 :)
drvdijk
1
Le fil @MaartenBodewes n'a rien au formatage visible, mais l'opération de type natif
Jacek Cz
147

Que diriez-vous:

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

L'idée n'est pas la mienne . Je l'ai repris d' un article sur dzone.com .

Grzegorz Oledzki
la source
44
Je vois votre point de vue, mais pour cette tâche particulière, «mon» code est plus déclaratif et plus clair que certains ByteBuffer «magiques», que l'on doit vérifier pour voir ce qu'il fait.
Grzegorz Oledzki
24
@Kevin - c'est très dur - il y a beaucoup de cas où ce type de code est approprié, par exemple dans le traitement d'image. Les bibliothèques JDK sont excellentes en général, mais elles ne couvrent pas et / ou ne sont pas optimisées pour tous les cas d'utilisation.
mikera
14
D'accord; la surcharge et la complexité de ByteBuffer peuvent ne pas être appropriées par rapport à certaines opérations d'octets simples et bien connues.
swdunlop
6
Un autre point que j'ajouterais est que vous avez utilisé l'opérateur de décalage droit non signé >>>plutôt que l'opérateur de décalage droit >>( docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html ) donc le comportement peut ne pas être comme souhaité / comme prévu avec des nombres signés et non signés
RobV
4
Cette approche semble être un peu plus rapide que les méthodes ByteBuffer ou BigInteger mentionnées. Quelque chose d'autre à prendre en compte si vous effectuez beaucoup de conversions.
chercheur
45

BigInteger.valueOf(1695609641).toByteArray()

vmpn
la source
2
quelle garantie avez-vous que cela produira un tableau de 4 octets?
MeBigFatGuy
2
Exactement ce que MeBigFatGuy a écrit. Javadoc of BigInteger.toByteArray()states: "Le tableau contiendra le nombre minimum d'octets requis pour représenter ce BigInteger ..."
icza
2
Où dans la question demande-t-il que le tableau d'octets soit de longueur fixe 4? Selon l'algorithme dont il est censé faire partie, vous pouvez utiliser la longueur du tableau
vmpn
c'est beaucoup plus dynamique et devrait être la bonne réponse. Vous pouvez simplement ajouter un tableau pour créer la taille souhaitée si vous le souhaitez. Surtout lorsque vous devez prendre en compte les valeurs int signées Java.
Droid Chris du
2
Cela semble créer un octet pour 0x7f et deux octets pour 0x80 (les deux octets étant: 0x0 0x80).
Scot
26
byte[] IntToByteArray( int data ) {    
    byte[] result = new byte[4];
    result[0] = (byte) ((data & 0xFF000000) >> 24);
    result[1] = (byte) ((data & 0x00FF0000) >> 16);
    result[2] = (byte) ((data & 0x0000FF00) >> 8);
    result[3] = (byte) ((data & 0x000000FF) >> 0);
    return result;        
}
Yury Finchenko
la source
22

Utilisation de la goyave :

byte[] bytearray = Ints.toByteArray(1695609641);
Aleksandr Dubinsky
la source
7
byte[] conv = new byte[4];
conv[3] = (byte) input & 0xff;
input >>= 8;
conv[2] = (byte) input & 0xff;
input >>= 8;
conv[1] = (byte) input & 0xff;
input >>= 8;
conv[0] = (byte) input;
Carl Smotricz
la source
2
Cela extrait les 8 octets les moins significatifs. Cela évite également de faire glisser le signe du numéro d'entrée dans l'octet converti.
Carl Smotricz
stackoverflow.com/questions/35305634/… - pouvez-vous s'il vous plaît résoudre ce C # en Java?
5
public static byte[] intToBytes(int x) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(bos);
    out.writeInt(x);
    out.close();
    byte[] int_bytes = bos.toByteArray();
    bos.close();
    return int_bytes;
}
lyon819
la source
4

Les morceaux ci-dessous fonctionnent au moins pour envoyer un int via UDP.

int en tableau d'octets:

public byte[] intToBytes(int my_int) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutput out = new ObjectOutputStream(bos);
    out.writeInt(my_int);
    out.close();
    byte[] int_bytes = bos.toByteArray();
    bos.close();
    return int_bytes;
}

tableau d'octets en int:

public int bytesToInt(byte[] int_bytes) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(int_bytes);
    ObjectInputStream ois = new ObjectInputStream(bis);
    int my_int = ois.readInt();
    ois.close();
    return my_int;
}
HaoQi Li
la source
4
l'utilisation d'ObjectOutputStream est incorrecte. Utilisez DataOutputStream, l'utilisation d'OOS fait en sorte que le tableau d'octets ne soit pas de 4 octets.
MeBigFatGuy
2

Étant donné que vous souhaitez généralement reconvertir ce tableau en un entier ultérieurement, voici les méthodes pour convertir un tableau d'entiers en un tableau d'octets et vice-versa:

public static byte[] convertToByteArray(final int[] pIntArray)
{
    final byte[] array = new byte[pIntArray.length * 4];
    for (int j = 0; j < pIntArray.length; j++)
    {
        final int c = pIntArray[j];
        array[j * 4] = (byte)((c & 0xFF000000) >> 24);
        array[j * 4 + 1] = (byte)((c & 0xFF0000) >> 16);
        array[j * 4 + 2] = (byte)((c & 0xFF00) >> 8);
        array[j * 4 + 3] = (byte)(c & 0xFF);
    }
    return array;
}

public static int[] convertToIntArray(final byte[] pByteArray)
{
    final int[] array = new int[pByteArray.length / 4];
    for (int i = 0; i < array.length; i++)
        array[i] = (((int)(pByteArray[i * 4]) << 24) & 0xFF000000) |
                (((int)(pByteArray[i * 4 + 1]) << 16) & 0xFF0000) |
                (((int)(pByteArray[i * 4 + 2]) << 8) & 0xFF00) |
                ((int)(pByteArray[i * 4 + 3]) & 0xFF);
    return array;
}

Notez qu'en raison de la propagation des signes et autres, les "& 0xFF ..." sont nécessaires lors de la reconversion en int.

jytou
la source
1
integer & 0xFF

pour le premier octet

(integer >> 8) & 0xFF

pour la deuxième boucle et etc., en écrivant dans un tableau d'octets préalloué. Un peu désordonné, malheureusement.

Brian Agnew
la source
1

La classe org.apache.hadoop.hbase.util.Bytes a un tas de méthodes de conversion byte [] pratiques, mais vous ne voudrez peut-être pas ajouter tout le fichier HBase à votre projet uniquement dans ce but. Il est surprenant que non seulement une telle méthode manque AFAIK du JDK, mais aussi des bibliothèques évidentes comme commons io.

mlohbihler
la source
1

Mon essai:

public static byte[] toBytes(final int intVal, final int... intArray) {
    if (intArray == null || (intArray.length == 0)) {
        return ByteBuffer.allocate(4).putInt(intVal).array();
    } else {
        final ByteBuffer bb = ByteBuffer.allocate(4 + (intArray.length * 4)).putInt(intVal);
        for (final int val : intArray) {
            bb.putInt(val);
        }
        return bb.array();
    }
}

Avec lui, vous pouvez faire ceci:

byte[] fourBytes = toBytes(0x01020304);
byte[] eightBytes = toBytes(0x01020304, 0x05060708);

La classe complète est ici: https://gist.github.com/superbob/6548493 , il prend en charge l'initialisation à partir de courts ou longs

byte[] eightBytesAgain = toBytes(0x0102030405060708L);
superbob
la source
1

Si vous utilisez apache-commons

public static byte[] toByteArray(int value) {
    byte result[] = new byte[4];
    return Conversion.intToByteArray(value, 0, result, 0, 4);
}
Neeraj
la source