Numero intero Java per array di byte


191

Ho un numero intero: 1695609641

quando uso il metodo:

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

dà:

6510f329

ma voglio un array di byte:

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

Come posso farlo?



Risposte:


294

l'utilizzo di ByteBuffer di Java NIO è molto semplice:

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

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

produzione:

0x65 0x10 0xf3 0x29 

4
Oppure usa il formato "0x%02X"se vuoi sempre due caratteri esadecimali nonché caratteri esadecimali maiuscoli, ad esempio System.out.format("0x%02X", (byte) 10)display 0x0A.
Maarten Bodewes,

12
È possibile utilizzare Integer.SIZE / 8 per evitare la codifica 4, che è un modello che funziona bene per altri tipi come Long.
davenpcj,

3
@davenpcj Puoi persino usare Integer.SIZE / Byte.SIZE
rkosegi

11
@rkosegi O addirittura Integer.BYTES da Java 8 :)
drvdijk,

1
Il thread @MaartenBodewes non ha nulla a che vedere con la formattazione, ma l'operazione di tipo nativo
Jacek Cz,

147

Che ne dite di:

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

L'idea non è mia . L'ho preso da qualche post su dzone.com .


44
Vedo il tuo punto, ma per questo particolare compito il "mio" codice è più dichiarativo e chiaro di un ByteBuffer "magico", che si deve controllare per vedere cosa fa.
Grzegorz Oledzki,

24
@Kevin - è molto duro - ci sono molti casi in cui questo tipo di codice è appropriato, ad esempio nell'elaborazione delle immagini. Le librerie JDK sono ottime in generale, ma non coprono e / o non sono ottimizzate per tutti i casi d'uso.
Mikera,

14
concordato; il sovraccarico e la complessità di ByteBuffer potrebbero non essere appropriati rispetto ad alcune operazioni byte semplici e ben note.
swdunlop,

6
Un altro punto che aggiungerei è che hai utilizzato l'operatore di spostamento a destra senza segno >>>anziché l'operatore di spostamento a destra >>( docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html ), quindi il comportamento potrebbe non essere come desiderato / come previsto con numeri firmati vs non firmati
RobV

4
Questo approccio sembra essere un po 'più veloce dei metodi ByteBuffer o BigInteger menzionati. Qualcos'altro da tenere in considerazione se farai molte conversioni.
cercatore

45

BigInteger.valueOf(1695609641).toByteArray()


2
che garanzia hai che produrrà un array di 4 byte?
MeBigFatGuy

2
Esattamente quello che ha scritto MeBigFatGuy. Javadoc degli BigInteger.toByteArray()stati: "L'array conterrà il numero minimo di byte richiesti per rappresentare questo BigInteger ..."
icza

2
Dove nella domanda chiede che l'array di byte abbia una lunghezza fissa 4? A seconda dell'algoritmo, ciò significa che far parte di te può utilizzare la lunghezza dell'array
vmpn

questo è molto più dinamico e dovrebbe essere la risposta giusta. Puoi semplicemente fare un'appendice Array per creare la dimensione desiderata, se lo desideri. Soprattutto quando si devono considerare i valori int con firma Java.
Droid Chris,

2
Questo sembra creare un byte per 0x7f e due byte per 0x80 (i due byte sono: 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
Ciò estrae gli 8 byte meno significativi. Evita inoltre di trascinare il segno del numero di input nell'ottetto convertito.
Carl Smotricz,

stackoverflow.com/questions/35305634/… - puoi risolvere questo C # in 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

I blocchi seguenti funzionano almeno per l'invio di un int su UDP.

int alla matrice di byte:

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

array di byte in 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'uso di ObjectOutputStream non è corretto. Usa DataOutputStream, l'uso di OOS lo rende quindi l'array di byte non è di 4 byte.
MeBigFatGuy

2

Poiché in genere si desidera riconvertire questo array in un int in un momento successivo, ecco i metodi per convertire un array di ints in un array di byte e viceversa:

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

Si noti che a causa della propagazione dei segni e simili, "& 0xFF ..." sono necessari per la riconversione in int.


1
integer & 0xFF

per il primo byte

(integer >> 8) & 0xFF

per il secondo e il ciclo ecc., scrivendo in una matrice di byte preallocata. Un po 'disordinato, sfortunatamente.


1

La classe org.apache.hadoop.hbase.util.Bytes ha un sacco di utili metodi di conversione byte [], ma potresti non voler aggiungere l'intero vaso HBase al tuo progetto solo per questo scopo. È sorprendente che non solo a tale metodo manchi AFAIK dal JDK, ma anche da ovvie librerie come i comuni.


1

Il mio tentativo:

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

Con esso puoi fare questo:

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

La classe completa è qui: https://gist.github.com/superbob/6548493 , supporta l'inizializzazione da short o long

byte[] eightBytesAgain = toBytes(0x0102030405060708L);

1

Se stai usando apache-commons

public static byte[] toByteArray(int value) {
    byte result[] = new byte[4];
    return Conversion.intToByteArray(value, 0, result, 0, 4);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.