Java Integer to Byte Array


190

Ich habe eine ganze Zahl: 1695609641

wenn ich Methode benutze:

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

gibt:

6510f329

aber ich möchte ein Byte-Array:

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

Wie kann ich das machen?



Antworten:


293

Die Verwendung von ByteBuffer von Java NIO ist sehr einfach:

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

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

Ausgabe:

0x65 0x10 0xf3 0x29 

4
Oder verwenden Sie das Format, "0x%02X"wenn Sie immer zwei hexadezimale Zeichen sowie hexadezimale Großbuchstaben, z . B. System.out.format("0x%02X", (byte) 10)Anzeigen, möchten 0x0A.
Maarten Bodewes

12
Sie können Integer.SIZE / 8 verwenden, um eine Hardcodierung der 4 zu vermeiden. Dieses Muster eignet sich gut für andere Typen wie Long.
Davenpcj

3
@davenpcj Sie können sogar Integer.SIZE / Byte.SIZE
rkosegi

11
@rkosegi Oder sogar Integer.BYTES seit Java 8 :)
drvdijk

1
@ MaartenBodewes Thread hat nichts zu sichtbarer Formatierung, aber native Typ Operation
Jacek Cz

146

Wie wäre es mit:

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

Die Idee ist nicht meine . Ich habe es einem Beitrag auf dzone.com entnommen .


44
Ich verstehe Ihren Standpunkt, aber für diese spezielle Aufgabe ist "mein" Code deklarativer und klarer als irgendein "magischer" ByteBuffer, den man überprüfen muss, um zu sehen, was er tut.
Grzegorz Oledzki

24
@ Kevin - das ist sehr hart - es gibt viele Fälle, in denen diese Art von Code angemessen ist, z. B. in der Bildverarbeitung. Die JDK-Bibliotheken sind im Allgemeinen großartig, decken jedoch nicht alle Anwendungsfälle ab und / oder sind nicht für diese optimiert.
Mikera

14
einverstanden; Der Overhead und die Komplexität von ByteBuffer sind im Vergleich zu einigen einfachen und bekannten Byteoperationen möglicherweise nicht angemessen.
Swdunlop

6
Ein weiterer Punkt, den ich hinzufügen möchte, ist, dass Sie den nicht signierten rechten Schichtoperator >>>anstelle des rechten Schichtoperators verwendet haben >>( docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html ), sodass das Verhalten möglicherweise nicht wie gewünscht ist. wie erwartet mit signierten und nicht signierten Nummern
RobV

4
Dieser Ansatz scheint etwas schneller zu sein als die genannten ByteBuffer- oder BigInteger-Methoden. Etwas anderes, das Sie berücksichtigen sollten, wenn Sie viele Conversions durchführen.
Sucher

45

BigInteger.valueOf(1695609641).toByteArray()


2
Welche Garantie haben Sie, dass ein 4-Byte-Array erzeugt wird?
MeBigFatGuy

2
Genau das, was MeBigFatGuy geschrieben hat. Javadoc von BigInteger.toByteArray()Staaten: "Das Array wird die minimale Anzahl von Bytes enthalten, die erforderlich sind, um diese BigInteger
darzustellen

2
Wo in der Frage wird gefragt, ob das Byte-Array eine feste Länge von 4 haben soll? Abhängig vom Algorithmus soll dies ein Teil von Ihnen sein. Sie können die Länge des Arrays nutzen
vmpn

Dies ist viel dynamischer und sollte die richtige Antwort sein. Sie können einfach ein Array anhängen, um die gewünschte Größe zu erstellen, wenn Sie möchten. Insbesondere, wenn Sie Java-signierte int-Werte berücksichtigen müssen.
Droid Chris

2
Dies scheint ein Byte für 0x7f und zwei Bytes für 0x80 zu erzeugen (die zwei Bytes sind: 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
Das extrahiert die niedrigstwertigen 8 Bytes. Außerdem wird vermieden, dass das Vorzeichen der eingegebenen Nummer in das konvertierte Oktett gezogen wird.
Carl Smotricz

stackoverflow.com/questions/35305634/… - können Sie dieses C # bitte in Java lösen?

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

Die folgenden Blöcke funktionieren zumindest zum Senden eines Int über UDP.

int to byte array:

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

Byte-Array zu 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
Die Verwendung von ObjectOutputStream ist falsch. Verwenden Sie DataOutputStream. Wenn Sie OOS verwenden, ist das Byte-Array nicht 4 Byte groß.
MeBigFatGuy

2

Da Sie dieses Array im Allgemeinen zu einem späteren Zeitpunkt wieder in ein int konvertieren möchten, finden Sie hier die Methoden zum Konvertieren eines Ints-Arrays in ein Byte-Array und umgekehrt:

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

Beachten Sie, dass aufgrund der Vorzeichenausbreitung und dergleichen "& 0xFF ..." beim Zurückkonvertieren in das int benötigt wird.


1
integer & 0xFF

für das erste Byte

(integer >> 8) & 0xFF

für die zweite und Schleife usw. in ein vorab zugewiesenes Byte-Array schreiben. Leider etwas chaotisch.


1

Die Klasse org.apache.hadoop.hbase.util.Bytes verfügt über eine Reihe praktischer Konvertierungsmethoden für Byte []. Möglicherweise möchten Sie jedoch nicht nur zu diesem Zweck das gesamte HBase-JAR zu Ihrem Projekt hinzufügen. Es ist überraschend, dass solche Methoden nicht nur AFAIK im JDK fehlen, sondern auch in offensichtlichen Bibliotheken wie Commons Io.


1

Mein Versuch:

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

Damit können Sie Folgendes tun:

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

Die vollständige Klasse finden Sie hier: https://gist.github.com/superbob/6548493 . Sie unterstützt die Initialisierung von Shorts oder Long

byte[] eightBytesAgain = toBytes(0x0102030405060708L);

1

Wenn Sie Apache-Commons verwenden

public static byte[] toByteArray(int value) {
    byte result[] = new byte[4];
    return Conversion.intToByteArray(value, 0, result, 0, 4);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.