Java uint32(长存储)到 4 字节数组

Java uint32 (stored as long) to 4 byte array

我正在写入具有 uint32 的存储格式,最大允许值为“4294967295”。

Java 中的整数当然是“2147483647”的一半以下。所以在内部,我必须使用 Long 或 Guava 的 UnsignedInteger。

要写入此格式,字节数组长度需要为 4,这正好适合 Integer,但将 Long 转换为字节数组需要长度为 8 的数组。

如何将表示最大值“4294967295”的 Long 或 UnsignedInteger 转换为 4 字节数组?

只需将其转换为8字节数组,然后只取最后4个字节即可:

 public static byte[] fromUnsignedInt(long value)
 {
     byte[] bytes = new byte[8];
     ByteBuffer.wrap(bytes).putLong(value);

     return Arrays.copyOfRange(bytes, 4, 8);
 }

要扭转这一点,您可以使用以下方法:

 public static long toUnsignedInt(byte[] bytes)
 {
     ByteBuffer buffer = ByteBuffer.allocate(8).put(new byte[]{0, 0, 0, 0}).put(bytes);
     buffer.position(0);

     return buffer.getLong();
 }

请注意,此方法可以采用负 long 或超出 unsigned int 范围的 long,并且在这种情况下不会抛出异常!

您可以将其转换为 int 并执行任何将 int 转换为数组的操作,例如:(未测试)

public static byte[] getUnsignedInt(long value)
{
    byte[] bytes = new byte[4];
    ByteBuffer.wrap(bytes).putInt((int)value);
    return bytes;
}

当然,如果您无论如何都将这些东西放在 ByteBuffer 中,您不妨直接这样做。

最高位的"meaning"或"interpretation"是无关紧要的,如果你只是在存储它。例如,4294967295 将被解释为 -1,但它实际上是相同的数字:十六进制的 0xFFFFFFFF,因此您将得到字节数组 { 0xFF, 0xFF, 0xFF, 0xFF }.

要反转它,你可以这样做(未测试)

public static long toUnsignedInt(byte[] bytes)
{
    ByteBuffer buffer = ByteBuffer.allocate(4).put(bytes);
    buffer.position(0);
    return buffer.getInt() & 0xFFFFFFFFL;
}

没有创建对象和复制已接受答案的数组的答案...使用移位操作很容易自己做。参见:

import java.io.*;

public class TestUINT32 {

  public static void writeLongAsUINT32(long value, OutputStream os) throws IOException {
    for (int i=0; i<4; ++i) {
      os.write((byte) value);
      value = value >> 8;
    }
  }

  public static void main(String[] args) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    long value = 0xFFEEDDBB;
    writeLongAsUINT32(value, os);
    byte[] ba = os.toByteArray();
    for (int i=ba.length; i>0; --i) {
      System.out.print(String.format("%02X", ba[i-1]));
    }
    System.out.println();
  }

}

示例运行:

$ java TestUINT32 
FFEEDDBB