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
我正在写入具有 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