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}

Renoncule
la source
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); }
Gregory Pakosz
la source
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();
}
Pascal Thivent
la source
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

daz
la source
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.

Serrement
la source
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.

notnoop
la source
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();

Helmy
la source
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);
Mukesh Bambhaniya
la source
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));
    }
}
wai
la source
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
Mat
la source
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;
};
utilisateur3424779
la source
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;
}
Muskovets
la source