Mengonversi integer menjadi byte array (Java)

137

apa cara cepat untuk mengubah an Integermenjadi Byte Array?

misalnya 0xAABBCCDD => {AA, BB, CC, DD}

cangkir mentega
sumber
1
Apakah penting format array byte yang dihasilkan? apa yang akan kamu lakukan dengan itu?
Skaffman

Jawaban:

238

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

Mengatur memastikan urutan byte yang result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCdan result[3] == 0xDD.

Atau sebagai alternatif, Anda dapat melakukannya secara manual:

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

The ByteBufferkelas dirancang untuk tangan kotor tugas-tugas seperti sekalipun. Faktanya, privat java.nio.Bitsmendefinisikan metode pembantu yang digunakan oleh 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
sumber
3
ini akan bekerja dengan baik jika bytebuffer sudah ada di sana ... jika tidak, sepertinya akan membutuhkan waktu lebih lama untuk melakukan alokasi, daripada hanya mengalokasikan array byte dengan panjang 4 dan melakukan perpindahan secara manual ... tetapi kita mungkin sedang membicarakan tentang perbedaan kecil.
Jason S
Instance ByteBuffer bisa di-cache; dan secara internal pasti diimplementasikan dengan shifting dan masking.
Gregory Pakosz
4
Ini adalah jawaban yang sangat bagus. Perhatikan bahwa big-endian adalah default yang ditentukan, dan metodenya "dapat dirantai", dan argumen posisi bersifat opsional, jadi semuanya berkurang menjadi: byte [] result = ByteBuffer.allocate (4) .putInt (0xAABBCCDD) .array ( ); Tentu saja, jika Anda melakukan ini berulang kali dan menggabungkan semua hasil bersama-sama (yang biasa terjadi saat Anda melakukan hal semacam ini), alokasikan satu buffer dan berulang kali putFoo () semua hal yang Anda butuhkan - itu akan melacak offset saat Anda pergi. Ini benar-benar kelas yang sangat berguna.
Kevin Bourrillion
apa yang dibawa pada tipe yang ditandatangani?
Gregory Pakosz
3
Untuk siapa yang tidak tahu. PutInt akan selalu menulis 4 byte, berapa pun ukuran bilangan bulat inputnya. Jika Anda hanya ingin 2 byte, gunakan putShort, dll ...
bvdb
37

Menggunakan BigInteger:

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

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

Menggunakan ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}
Pascal Thivent
sumber
5
perhatikan urutan byte meskipun
Gregory Pakosz
1
Apakah ByteBuffer memberikan int unsigned?
Arun George
@Pascal Menggunakan ByteBuffer Saya mencoba dengan ByteBuffer bb = ByteBuffer.allocate (3); Untuk ini memberikan java.nio.BufferOverflowException, saya tidak mengerti mengapa tidak berfungsi untuk nilai kurang dari 4? Bisakah Anda menjelaskan?
Sanjay Jain
@SanjayJain Anda mendapatkan pengecualian buffer overflow karena int di Java berukuran 32-bit atau 4 byte, dan oleh karena itu mengharuskan Anda mengalokasikan setidaknya 4 byte memori di ByteBuffer Anda.
mengejutkan
@GregoryPakosz benar tentang urutan byte. Jawabannya menggunakan ByteBufferlebih intuitif jika Anda berurusan dengan int lebih besar dari 2 ^ 31 - 1.
ordonezalex
31

gunakan fungsi ini, ini berfungsi untuk saya

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

itu menerjemahkan int menjadi nilai byte

daz
sumber
Ini juga tidak ada gunanya bahwa ini akan berfungsi terlepas dari bit yang paling signifikan dan lebih efisien dibandingkan dengan jawaban lain. Juga bisa menggunakan '>>'.
algolicious
1
Solusi langsung seperti ini tentu lebih cepat daripada memanggil metode perpustakaan apa pun. Kadang-kadang Anda hanya perlu mengutak-atik bit secara langsung dengan beberapa baris kode daripada menimbulkan semua overhead tambahan dari panggilan metode library.
David R Tribble
Dan ini mengubah antar bahasa dengan baik sehingga bagus untuk pengembangan perangkat lunak multi bahasa.
Koordinator
16

Jika Anda menyukai Jambu biji , Anda dapat menggunakan Intskelasnya:


Untuk intbyte[], gunakan toByteArray():

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

Hasilnya adalah {0xAA, 0xBB, 0xCC, 0xDD}.


Kebalikannya adalah fromByteArray()atau 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);

Hasilnya adalah 0xAABBCCDD.

Pang
sumber
8

Anda dapat menggunakan BigInteger:

Dari Integers:

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

Array yang dikembalikan adalah ukuran yang diperlukan untuk mewakili angka, sehingga bisa berukuran 1, untuk mewakili 1 misalnya. Namun, ukurannya tidak boleh lebih dari empat byte jika int dilewatkan.

Dari Strings:

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

Namun, Anda harus berhati-hati, jika byte pertama lebih tinggi 0x7F(seperti dalam kasus ini), di mana BigInteger akan memasukkan 0x00 byte ke awal array. Ini diperlukan untuk membedakan antara nilai positif dan negatif.

notnoop
sumber
Terima kasih! Tetapi karena ini BigInteger, akankah int membungkus dengan benar? Itu adalah bilangan bulat yang berada di luar Integer.MAX_VALUE tetapi masih dapat direpresentasikan dengan hanya 4 byte?
Buttercup
1
Ini tentu tidak cepat untuk dieksekusi. ;)
Peter Lawrey
Ini bukan pilihan yang bagus. Tidak hanya dapat menambahkan 0x00 byte, itu juga dapat menghilangkan nol di depan.
ZZ Coder
1

Solusi sederhana yang menangani ByteOrder dengan benar:

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

helmy
sumber
1

sangat mudah dengan 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
sumber
1

Ini akan membantumu.

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
sumber
0

Bisa juga menggeser -

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
Matt
sumber
0

Berikut adalah metode yang akan melakukan pekerjaan dengan benar.

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;
};
pengguna3424779
sumber
0

Ini solusi saya:

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

Juga Stringmetode y:

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
sumber