Tableau d'entiers Java en octets


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 

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 .


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()


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;        
}


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;

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;
}

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;
}

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.


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.


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.


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);

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);
}
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.