จำนวนเต็ม Java เป็นไบต์อาร์เรย์


191

ฉันได้รับจำนวนเต็ม: 1695609641

เมื่อฉันใช้วิธีการ:

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

ให้:

6510f329

แต่ฉันต้องการอาร์เรย์ไบต์:

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

ฉันจะทำสิ่งนี้ได้อย่างไร


4
ทำซ้ำที่เป็นไปได้ของการแปลงจำนวนเต็มเป็นไบต์อาร์เรย์ (Java)
finnw

สำเนาซ้ำที่เป็นไปได้ของการแปลงจำนวนเต็มเป็นไบต์อาร์เรย์ (Java)
Tacodude7729

คำตอบ:


294

การใช้ByteBufferของ Java NIO นั้นง่ายมาก:

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

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

เอาท์พุท:

0x65 0x10 0xf3 0x29 

4
หรือใช้รูปแบบ"0x%02X"ถ้าคุณมักจะต้องการตัวละครทั้งสองเลขฐานสิบหกเช่นเดียวกับ hexadecimals พิมพ์ใหญ่เช่นการแสดงSystem.out.format("0x%02X", (byte) 10) 0x0A
Maarten Bodewes

12
คุณสามารถใช้ Integer.SIZE / 8 เพื่อหลีกเลี่ยงการเข้ารหัสแบบ 4 ซึ่งเป็นรูปแบบที่ทำงานได้ดีสำหรับประเภทอื่นเช่น Long
davenpcj

3
@davenpcj คุณสามารถใช้ Integer.SIZE / Byte.SIZE
rkosegi

11
@rkosegi หรือแม้แต่ Integer.BYTES ตั้งแต่ Java 8 :)
drvdijk

1
@MaartenBodewes เธรดไม่มีสิ่งใดในการจัดรูปแบบที่มองเห็นได้ แต่การดำเนินการในรูปแบบดั้งเดิม
Jacek Cz

147

เกี่ยวกับ:

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

ความคิดที่จะไม่ระเบิด ฉันเอามันออกมาจากการโพสต์บางอย่างเกี่ยวกับ dzone.com


44
ฉันเห็นประเด็นของคุณ แต่สำหรับงานนี้ 'รหัส' ของฉันนั้นชัดเจนและชัดเจนยิ่งกว่า ByteBuffer 'เวทมนต์' ซึ่งบางคนต้องตรวจสอบเพื่อดูว่ามันทำอะไร
Grzegorz Oledzki

24
@ เควิน - มันรุนแรงมาก - มีหลายกรณีที่รหัสประเภทนี้เหมาะสมเช่นในการประมวลผลภาพ โดยทั่วไปไลบรารี JDK นั้นยอดเยี่ยม แต่ไม่ครอบคลุมและ / หรือไม่เหมาะสำหรับการใช้งานทุกกรณี
mikera

14
ตกลงกัน; ค่าใช้จ่ายและความซับซ้อนของ ByteBuffer อาจไม่เหมาะสมเมื่อเทียบกับการดำเนินงานไบต์ที่เรียบง่ายและเป็นที่รู้จักกันดี
swdunlop

6
อีกจุดที่ฉันเพิ่มคือคุณใช้ตัวดำเนินการกะด้านขวาที่ไม่ได้ลงชื่อ>>>แทนที่จะเป็นตัวดำเนินการกะขวา>>( docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html ) ดังนั้นพฤติกรรมอาจไม่เป็นที่ต้องการ / ตามที่คาดไว้กับหมายเลขที่ลงนามแล้วกับตัวเลขที่ไม่ได้ลงนาม
RobV

4
วิธีนี้ดูเหมือนจะเร็วกว่าวิธีการ ByteBuffer หรือ BigInteger ที่กล่าวถึง สิ่งอื่นที่ต้องคำนึงถึงหากคุณจะทำ Conversion มากมาย
ผู้สมัคร

45

BigInteger.valueOf(1695609641).toByteArray()


2
สิ่งที่รับประกันคุณมีที่จะผลิตอาร์เรย์ 4 ไบต์?
MeBigFatGuy

2
สิ่งที่ MeBigFatGuy เขียน Javadoc of BigInteger.toByteArray()states: "อาร์เรย์จะมีจำนวนไบต์ขั้นต่ำที่จำเป็นในการเป็นตัวแทน BigInteger นี้ ... "
icza

2
ในคำถามถามว่าอาร์เรย์ไบต์มีความยาวคงที่ 4 อยู่ที่ไหน ทั้งนี้ขึ้นอยู่กับอัลกอริทึมซึ่งเป็นส่วนหนึ่งของคุณที่สามารถใช้ความยาวของอาเรย์ได้
vmpn

นี่เป็นแบบไดนามิกมากขึ้นและควรเป็นคำตอบที่ถูกต้อง คุณสามารถเพิ่ม Array ต่อท้ายเพื่อสร้างขนาดที่ต้องการได้ตามต้องการ พิเศษเมื่อคุณต้องพิจารณาจาวาค่า int int
Droid Chris

2
ดูเหมือนว่าจะสร้างหนึ่งไบต์สำหรับ 0x7f และสองไบต์สำหรับ 0x80 (สองไบต์นั้นเป็น: 0x0 0x80)
สกอต

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
ที่แยกอย่างมีนัยสำคัญอย่างน้อย 8 ไบต์ นอกจากนี้ยังหลีกเลี่ยงการลากเครื่องหมายของหมายเลขอินพุทไปยังออคเต็ตที่ถูกแปลง
Carl Smotricz

stackoverflow.com/questions/35305634/… - คุณช่วยแก้ C # นี้ให้เป็น 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

ชิ้นต่อไปนี้ทำงานอย่างน้อยสำหรับการส่ง int ผ่าน UDP

int ถึงอาร์เรย์ไบต์:

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

อาร์เรย์ไบต์เป็น 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
การใช้ ObjectOutputStream ไม่ถูกต้อง ใช้ DataOutputStream การใช้ OOS ทำให้มันเป็นอาร์เรย์ไบต์ไม่ได้ 4 ไบต์
MeBigFatGuy

2

เนื่องจากโดยทั่วไปคุณต้องการแปลงอาร์เรย์นี้กลับไปเป็น int ในภายหลังนี่คือวิธีการแปลงอาร์เรย์ของ ints เป็นอาร์เรย์ไบต์และในทางกลับกัน:

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

โปรดทราบว่าเนื่องจากการเผยแพร่สัญลักษณ์และจำเป็นต้องใช้ "& 0xFF ... " เมื่อแปลงกลับเป็น int


1
integer & 0xFF

สำหรับไบต์แรก

(integer >> 8) & 0xFF

สำหรับวินาทีและลูปเป็นต้นให้เขียนลงในอาร์เรย์ไบต์ที่จัดสรรล่วงหน้า น่าเสียดายเล็กน้อย


1

คลาส org.apache.hadoop.hbase.util.Bytes มีวิธีแปลงจำนวนมากสะดวก [] แต่คุณอาจไม่ต้องการเพิ่ม HBase jar ทั้งหมดลงในโครงการของคุณเพื่อจุดประสงค์นี้ มันน่าแปลกใจที่ไม่เพียง แต่วิธีดังกล่าวจะหายไปจาก AFAIK จาก JDK แต่ยังมาจาก libs ที่ชัดเจนเช่นคอมมอนส์ io


1

ความพยายามของฉัน:

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

ด้วยคุณสามารถทำสิ่งนี้:

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

คลาสเต็มอยู่ที่นี่: https://gist.github.com/superbob/6548493รองรับการเริ่มต้นจากกางเกงขาสั้นหรือยาว

byte[] eightBytesAgain = toBytes(0x0102030405060708L);

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.