将整数转换为字节数组(Java)

148

如何快速将 Integer 转换为 Byte Array

例如:0xAABBCCDD => {AA, BB, CC, DD}


2
结果的字节数组的格式是否重要呢?您对它有什么计划? - skaffman
11个回答

267

请查看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();

设置字节序可以确保 result[0] == 0xAAresult[1] == 0xBBresult[2] == 0xCCresult[3] == 0xDD

或者,您也可以手动完成此操作:

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

ByteBuffer 类专门为这种粗略的任务而设计。实际上,私有的 java.nio.Bits 定义了这些帮助方法,它们被 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
如果字节缓冲区已经存在,这个方法会很好用...否则似乎需要花更长的时间来分配内存,比起手动分配一个长度为4的字节数组再进行移位处理...不过我们可能只是在谈论一些很小的差异。 - Jason S
ByteBuffer实例可以被缓存;而且内部肯定是使用移位和掩码实现的。 - Gregory Pakosz
4
这是一个完全合适的答案。请注意,big-endian是指定的默认值,方法是“可链接的”,位置参数是可选的,因此可以简化为:byte[] result = ByteBuffer.allocate(4).putInt(0xAABBCCDD).array();当然,如果您需要重复执行此操作并将所有结果连接在一起(当您进行此类操作时很常见),请分配单个缓冲区并重复使用 putFoo()方法进入所需内容 - 它会在你执行的同时跟踪偏移量。这确实是一个非常有用的类。 - Kevin Bourrillion
有符号类型会带来什么影响? - Gregory Pakosz
1
如果您计划在随后的NIO写操作中使用该ByteBuffer,则需要将其“rewind”。否则,您将什么也不会写入!(我已经尝试过了!) - David J.
3
如果您不知道,putInt始终会写入4个字节,无论输入的整数大小如何。如果只需要2个字节,请使用putShort,等等... - bvdb

46

使用BigInteger

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

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

使用 ByteBuffer

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

6
请注意字节顺序。 - Gregory Pakosz
1
ByteBuffer是否返回无符号整数? - Arun George
@Pascal 使用 ByteBuffer 我尝试使用 ByteBuffer bb = ByteBuffer.allocate(3); 但是它会报 java.nio.BufferOverflowException 错误,我不明白为什么它不能处理小于4的值?你能解释一下吗? - Sanjay Jain
@SanjayJain,你之所以会出现缓冲区溢出异常,是因为Java中的int类型大小为32位或4个字节,因此在ByteBuffer中分配内存时需要至少4个字节。 - shocking

32

我用过这个函数,它对我有效

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

它将整数转换为字节值


值得注意的是,无论最高位是什么,这种方法都能正常运行,并且比其他答案更高效。也可以使用'>>'。 - algolicious
2
像这样的直接解决方案肯定比调用任何库方法更快。有时候,你只需要用几行代码直接操作位,而不是承担所有额外的库方法调用开销。 - David R Tribble
这个可以很好地在不同语言之间进行转换,因此非常适合多语言软件开发。 - The Coordinator

17

如果你喜欢Guava,可以使用它的Ints类:


int转换为byte[],请使用toByteArray()方法:

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

结果是{0xAA, 0xBB, 0xCC, 0xDD}


它的反转是fromByteArray()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);

结果为 0xAABBCCDD


9
你可以使用 BigInteger
从整数中获取:
byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

返回的数组大小与表示数字所需的大小相同,因此可以是大小为1的数组,例如用于表示1。但是,如果传递int,则大小不能超过四个字节。
从字符串:
BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

然而,需要注意的是,如果第一个字节大于0x7F(在这种情况下),BigInteger会在数组开头插入一个0x00字节。这是为了区分正数和负数。


但是由于这是BigInteger,int类型会正确地环绕吗?也就是说,整数超出了Integer.MAX_VALUE,但仍然可以用4个字节表示? - Buttercup
1
这肯定不是快速执行的。 ;) - Peter Lawrey
1
这不是一个好的选择。它不仅可能添加0x00字节,还可能剥夺前导零。 - ZZ Coder

3
可以使用shift键 -
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

2

以下是处理ByteOrder的简单解决方案:

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


请注意,这段代码能确保在不同系统上运行时字节顺序正确。

1
这里有一个方法,应该可以完美地完成任务。
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

这会对你有所帮助。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接