Java整数到字节数组


190

我得到一个整数: 1695609641

当我使用方法:

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

给出:

6510f329

但我想要一个字节数组:

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

我该怎么做?



Answers:


293

使用Java NIO的ByteBuffer非常简单:

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"如果您始终需要两个十六进制字符以及大写十六进制字符,请使用格式,例如System.out.format("0x%02X", (byte) 10)display 0x0A
Maarten Bodewes,2012年

12
您可以使用Integer.SIZE / 8避免对4进行硬编码,这是一种适用于Long等其他类型的模式。
davenpcj 2013年

3
@davenpcj您甚至可以使用Integer.SIZE / Byte.SIZE
rkosegi'2

11
@rkosegi甚至是Java 8以来的Integer.BYTES :)
drvdijk

1
@MaartenBodewes线程对可见格式没有任何内容,但是本机类型操作
Jacek Cz

146

怎么样:

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'2

24
@Kevin-非常苛刻-在很多情况下,例如在图像处理中,此类代码均适用。通常,JDK库很棒,但它们并未涵盖和/或未针对所有用例进行优化。
mikera 2011年

14
同意 与某些简单且众所周知的字节操作相比,ByteBuffer的开销和复杂性可能不合适。
swdunlop

6
我要补充的另一点是,您使用的是无符号右移运算符,>>>而不是右移运算符>>docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html),因此行为可能不符合要求/如预期的那样,有符号数与无符号数
RobV

4
这种方法似乎比提到的ByteBuffer或BigInteger方法要快一些。如果您要进行大量转换,还需要考虑其他因素。
搜寻者

45

BigInteger.valueOf(1695609641).toByteArray()


2
你有什么保证会产生一个4字节的数组?
MeBigFatGuy

2
正是MeBigFatGuy写的。BigInteger.toByteArray()状态的Javadoc :“数组将包含表示此BigInteger所需的最小字节数...”
icza 2013年

2
它在哪里要求字节数组的固定长度为4?根据算法,这意味着您可以利用阵列的长度
vmpn 2014年

这是动态的,应该是正确的答案。您可以根据需要简单地执行Array追加来创建所需的大小。特别是当您必须考虑Javasigned 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;        
}



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

下面的块至少可用于通过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 2013年

2

因为通常您会在以后将这个数组转换回int,所以这里是将int数组转换为bytes数组的方法,反之亦然:

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

注意,由于符号传播等原因,转换回int时需要使用“&0xFF ...”。


1
integer & 0xFF

对于第一个字节

(integer >> 8) & 0xFF

对于第二个和循环等,写入一个预分配的字节数组。不幸的是,有点混乱。


1

org.apache.hadoop.hbase.util.Bytes类具有许多方便的byte []转换方法,但是您可能不希望仅将整个HBase jar添加到您的项目中。令人惊讶的是,这种方法不仅缺少JDK的AFAIK,而且还缺少Commons 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);

1

如果您使用的是apache-commons

public static byte[] toByteArray(int value) {
    byte result[] = new byte[4];
    return Conversion.intToByteArray(value, 0, result, 0, 4);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.