Chuyển đổi số nguyên thành mảng byte (Java)


137

một cách nhanh chóng để chuyển đổi Integerthành một Byte Array?

ví dụ 0xAABBCCDD => {AA, BB, CC, DD}


1
Có vấn đề định dạng nào của mảng byte kết quả không? Bạn sẽ làm gì với nó?
skaffman

Câu trả lời:


237

Hãy xem lớp 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();

Thiết này để thỏa mãn thứ tự byte rằng result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCresult[3] == 0xDD.

Hoặc cách khác, bạn có thể làm điều đó bằng tay:

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

Các ByteBufferlớp được thiết kế cho các nhiệm vụ tay bẩn như vậy mặc dù. Trong thực tế, private java.nio.Bitsđịnh nghĩa các phương thức trợ giúp này được sử dụng bởi 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
điều này sẽ hoạt động tốt nếu bytebuffer đã có sẵn ... nếu không, có vẻ như sẽ mất nhiều thời gian hơn để phân bổ, hơn là chỉ phân bổ một mảng byte có độ dài 4 và thực hiện dịch chuyển thủ công ... nhưng có lẽ chúng ta đang nói chuyện về sự khác biệt nhỏ.
Jason S

Ví dụ ByteBuffer có thể được lưu trữ; và trong nội bộ, nó chắc chắn được thực hiện với sự thay đổi và mặt nạ.
Gregory Pakosz

4
Đây là một câu trả lời hoàn toàn tốt. Lưu ý rằng big-endian là mặc định được chỉ định và các phương thức là "có thể kết nối được" và đối số vị trí là tùy chọn, vì vậy tất cả giảm xuống: byte [] result = ByteBuffer.allocate (4) .putInt (0xAABBCCDD) .array ( ); Tất nhiên, nếu bạn đang thực hiện việc này nhiều lần và ghép tất cả các kết quả lại với nhau (điều này là phổ biến khi bạn thực hiện loại việc này), hãy phân bổ một bộ đệm duy nhất và liên tục đặtFoo () tất cả những thứ bạn cần - nó sẽ theo dõi bù đắp khi bạn đi. Đó thực sự là một lớp học rất hữu ích.
Kevin Bourrillion

những gì nó mang lại trên các loại đã ký?
Gregory Pakosz

3
Vì ai không biết. PutInt sẽ luôn ghi 4 byte, bất kể kích thước của số nguyên đầu vào là bao nhiêu. Nếu bạn chỉ muốn 2 byte, hãy sử dụng putShort, v.v ...
bvdb

36

Sử dụng BigInteger:

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

Sử dụng 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();
}

Sử dụng ByteBuffer:

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

5
chú ý đến thứ tự byte mặc dù
Gregory Pakosz

1
ByteBuffer có cung cấp một int unsign không?
Arun George

@Pascal Sử dụng ByteBuffer Tôi đã thử với ByteBuffer bb = ByteBuffer.allocate (3); Đối với điều này, nó mang lại cho java.nio.BufferOverflowException, tôi không hiểu tại sao nó không hoạt động với giá trị nhỏ hơn 4? Bạn có thể giải thích dùm không?
Sanjay Jain

@SanjayJain Bạn nhận được một ngoại lệ tràn bộ đệm vì ints trong Java có kích thước 32 bit hoặc 4 byte và do đó yêu cầu bạn phải phân bổ ít nhất 4 byte bộ nhớ trong ByteBuffer của bạn.
gây sốc

@GregoryPakosz đúng về thứ tự byte. Câu trả lời của anh ấy sử dụng ByteBuffertrực quan hơn nếu bạn giao dịch với số nguyên lớn hơn 2 ^ 31 - 1.
ordonezalex

31

sử dụng chức năng này nó hoạt động cho tôi

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

nó dịch int thành một giá trị byte


Điều này cũng không có giá trị gì khi điều này sẽ hoạt động bất kể bit quan trọng nhất và hiệu quả hơn so với các câu trả lời khác. Cũng có thể sử dụng '>>'.
algolicious

1
Một giải pháp trực tiếp như thế này chắc chắn nhanh hơn so với việc gọi bất kỳ phương thức thư viện nào. Đôi khi bạn chỉ cần mân mê các bit trực tiếp bằng một vài dòng mã thay vì phát sinh tất cả các chi phí phụ của các cuộc gọi phương thức thư viện.
David R Tribble

Và điều này chuyển đổi giữa các ngôn ngữ tốt vì vậy rất tốt cho phát triển phần mềm đa ngôn ngữ.
Điều phối viên

15

Nếu bạn thích ổi , bạn có thể sử dụng Intslớp của nó :


Đối với intbyte[], sử dụng toByteArray():

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

Kết quả là {0xAA, 0xBB, 0xCC, 0xDD}.


Đảo ngược của nó là fromByteArray()hoặc 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);

Kết quả là 0xAABBCCDD.


8

Bạn có thể sử dụng BigInteger:

Từ số nguyên:

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

Mảng trả về có kích thước cần thiết để đại diện cho số, vì vậy nó có thể có kích thước 1, để đại diện cho 1 chẳng hạn. Tuy nhiên, kích thước không thể nhiều hơn bốn byte nếu một int được truyền.

Từ chuỗi:

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

Tuy nhiên, bạn sẽ cần coi chừng, nếu byte đầu tiên cao hơn 0x7F(như trong trường hợp này), trong đó BigInteger sẽ chèn một byte 0x00 vào đầu mảng. Điều này là cần thiết để phân biệt giữa các giá trị tích cực và tiêu cực.


cảm ơn! Nhưng vì đây là BigInteger, liệu ints có bao bọc chính xác không? Đó là các số nguyên nằm ngoài Integer.MAX_VALUE nhưng vẫn có thể được biểu diễn chỉ với 4 byte?
Buttercup

1
Điều này chắc chắn không nhanh để thực hiện. ;)
Peter Lawrey

Đây không phải là một lựa chọn tốt. Không chỉ có thể thêm 0x00 byte, nó cũng có thể loại bỏ các số 0 đứng đầu.
ZZ

1

Giải pháp đơn giản xử lý đúng cách ByteOrder:

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


1

rất dễ dàng với 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

Điều này sẽ giúp bạn.

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

Cũng có thể thay đổi -

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

Đây là một phương pháp nên làm công việc vừa phải.

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

Đó là giải pháp của tôi:

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

Ngoài ra Stringphương pháp 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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.