Ganzzahl in Byte-Array konvertieren (Java)


137

Was ist ein schneller Weg, um eine Integerin eine umzuwandelnByte Array ?

z.B 0xAABBCCDD => {AA, BB, CC, DD}


1
Ist es wichtig, welches Format das resultierende Byte-Array hat? Was wirst du damit machen?
Skaffman

Antworten:


237

Schauen Sie sich die ByteBuffer- Klasse an.

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

Einstellen der Byte - Reihenfolge wird sichergestellt , dass result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCundresult[3] == 0xDD .

Alternativ können Sie dies auch manuell tun:

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

Die ByteBufferKlasse wurde jedoch für solche Aufgaben mit schmutzigen Händen entwickelt. Tatsächlich java.nio.Bitsdefiniert das Private diese Hilfsmethoden, die verwendet werden von 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); }

3
Dies würde gut funktionieren, wenn der Bytepuffer bereits vorhanden ist. Andernfalls scheint die Zuweisung länger zu dauern, als nur ein Byte-Array der Länge 4 zuzuweisen und die Verschiebung manuell durchzuführen. Aber wir sprechen wahrscheinlich über kleine Unterschiede.
Jason S

Die ByteBuffer-Instanz kann zwischengespeichert werden. und intern ist es sicherlich sowieso mit Verschieben und Maskieren implementiert.
Gregory Pakosz

4
Dies ist eine sehr gute Antwort. Beachten Sie, dass Big-Endian der angegebene Standardwert ist und die Methoden "verkettbar" sind und das Positionsargument optional ist. Daher reduziert sich alles auf: byte [] result = ByteBuffer.allocate (4) .putInt (0xAABBCCDD) .array ( ); Wenn Sie dies wiederholt tun und alle Ergebnisse miteinander verketten (was häufig der Fall ist, wenn Sie so etwas tun), weisen Sie natürlich einen einzelnen Puffer zu und setzen Sie wiederholt alle benötigten Dinge inFoo () ein - Es wird den Versatz verfolgen, während Sie gehen. Es ist wirklich eine unglaublich nützliche Klasse.
Kevin Bourrillion

Was bringt es auf signierten Typen?
Gregory Pakosz

3
Denn wer weiß es nicht. Das putInt schreibt immer 4 Bytes, unabhängig von der Größe der Eingabe-Ganzzahl. Wenn Sie nur 2 Bytes möchten, verwenden Sie putShort usw.
bvdb

36

Verwenden von BigInteger:

private byte[] bigIntToByteArray( final int i ) {
    BigInteger bigInt = BigInteger.valueOf(i);      
    return bigInt.toByteArray();
}

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

Verwenden von ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}


1
Gibt ByteBuffer ein vorzeichenloses int aus?
Arun George

@Pascal Mit ByteBuffer habe ich es mit ByteBuffer versucht bb = ByteBuffer.allocate (3); Dafür gibt es java.nio.BufferOverflowException, ich verstehe nicht, warum es nicht für einen Wert unter 4 funktioniert? Kannst du bitte Erklären?
Sanjay Jain

@SanjayJain Sie erhalten eine Pufferüberlaufausnahme, da Ints in Java 32 Bit oder 4 Byte groß sind und Sie daher mindestens 4 Byte Speicher in Ihrem ByteBuffer zuweisen müssen.
schockierend

@GregoryPakosz hat Recht mit der Bytereihenfolge. Seine Antwort mit ByteBufferist intuitiver, wenn Sie mit einem int größer als 2 ^ 31 - 1.
ordonezalex

31

Verwenden Sie diese Funktion, es funktioniert für mich

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

es übersetzt das int in einen Bytewert


Es ist auch nichts wert, dass dies unabhängig vom wichtigsten Punkt funktioniert und im Vergleich zu den anderen Antworten effizienter ist. Könnte auch '>>' verwenden.
Algolicious

1
Eine direkte Lösung wie diese ist sicherlich schneller als das Aufrufen einer Bibliotheksmethode. Manchmal muss man nur mit ein paar Codezeilen direkt mit den Bits herumspielen, anstatt den zusätzlichen Aufwand für Bibliotheksmethodenaufrufe zu verursachen.
David R Tribble

Und dies konvertiert gut zwischen Sprachen und ist daher gut für die mehrsprachige Softwareentwicklung.
Der Koordinator

15

Wenn Sie Guave mögen , können Sie seine IntsKlasse verwenden:


Für intbyte[]verwenden Sie toByteArray():

byte[] byteArray = Ints.toByteArray(0xAABBCCDD);

Ergebnis ist {0xAA, 0xBB, 0xCC, 0xDD}.


Seine Rückseite ist fromByteArray()oder 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);

Ergebnis ist 0xAABBCCDD.


8

Sie können verwenden BigInteger :

Aus ganzen Zahlen:

byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

Das zurückgegebene Array hat die Größe, die zur Darstellung der Zahl benötigt wird. Es kann also die Größe 1 haben, um beispielsweise 1 darzustellen. Die Größe darf jedoch nicht mehr als vier Byte betragen, wenn ein int übergeben wird.

Von Strings:

BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

Wenn das erste Byte höher ist 0x7F(wie in diesem Fall), müssen Sie jedoch darauf achten, dass BigInteger am Anfang des Arrays ein 0x00-Byte einfügt. Dies ist erforderlich, um zwischen positiven und negativen Werten zu unterscheiden.


Vielen Dank! Aber da dies BigInteger ist, werden Ints richtig herumlaufen? Das sind Ganzzahlen, die außerhalb von Integer.MAX_VALUE liegen, aber dennoch mit nur 4 Bytes dargestellt werden können?
Butterblume

1
Dies ist sicherlich nicht schnell auszuführen. ;)
Peter Lawrey

Dies ist keine gute Option. Es kann nicht nur 0x00 Byte hinzufügen, sondern auch führende Nullen entfernen.
ZZ Coder

1

Einfache Lösung, die ByteOrder richtig handhabt:

ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(yourInt).array();


1

sehr einfach mit 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);

1

Das wird dir helfen.

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

0

Kann auch verschieben -

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

0

Hier ist eine Methode, die den Job genau richtig machen sollte.

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

0

Es ist meine Lösung:

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

Auch Stringy Methode:

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